Context
I am currently making a program in Linux that uses SSL secured IPv4 sockets. Once the sockets are created they connect to an IP and make a request
socket->Connect( ip.c_str() , port );
socket->Write( request.c_str(), strlen(request.c_str()) );
After that I read the contents of the page in a loop with a buffer then I accumulate the contents of the buffer in a string. The buffer also cleans in each iteration to avoid overwriting the contents.
int bytes_read = 0;
char buffer[buffer_size]; // where buffer_size is an arbitrary number 512 for example
do {
socket->Read(buffer, buffer_size);
bytes_read = socket->Read(buffer, buffer_size);
result += buffer;
// std::cout << buffer << std::endl;
memset(buffer, 0, buffer_size);
} while (bytes_read > 0);
The code is pretty simple, as I said I use sockets with SSL connections but I do not use any extra flag on the socket. But once the program is run it take a considerable amount of time to finish even when connecting to pretty simple pages.
As a result of that I decided to type the content of the buffer in each iteration and I noticed that the program reads the content almost instantly but the program run for another 5 seconds before finishing it’s execution. In bigger pages like Wikipedia it doesn’t finish as I have to do Ctrl^z.
Therefore my question is, why is this happening? I don’t understand this behavior,the man page of read says as follows:
On success, the number of bytes read is returned (zero indicates
end of file), and the file position is advanced by this number.
It is not an error if this number is smaller than the number of
bytes requested; this may happen for example because fewer bytes
are actually available right now (maybe because we were close to
end-of-file, or because we are reading from a pipe, or from a
terminal), or because read() was interrupted by a signal
From what I understand once the EOF is reached it will return a 0 and then it should exit out of the loop.
The expected behaviour is of course to exit out of the loop once the contents have been read. As a matter of fact if I just do the read one time instead of looping through it the program finishes in < 1 seconds. This is however something I don’t want to implement as the function read can fail and not read all the bytes specified in size and I need to ensure that all the contents of the page are read.
What I have tried
So far I’ve tried to use a timeout in the socket
struct timeval timeout;
timeout.tv_sec = 10; // 10 secs
timeout.tv_usec = 0;
if (setsockopt(socket->getDescriptor(), SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
perror("setsockopt failed");
Aswell as making it non blocking
int flags = fcntl(sockfd, F_GETFL, 0);
But it has not worked. I would like to understand why is this happening and how can I ensure that all the contents of a page are read without having this problem where the program won’t end or will take a lot of time. I appreciate the help thank you.
DarPlays is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.