I have a non-blocking connection socket I accepted:
I have a non-blocking socket connection, and after receiving a packet of data, I attempt to read more using recv.
struct sockaddr accepted_address;
socklen_t accepted_address_size = sizeof(accepted_address);
int fd = accept(server_fd, &accepted_address, &accepted_address_size);
make_nonblocking(fd);
... // wait when socket is ready to give me data
char buffer[BUF_SIZE];
int used = 0;
while (true) {
int bytes_received = recv(fd, buffer, BUF_SIZE, 0);
if (bytes_received > 0) { /* OK */ }
else if (bytes_received < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Should wait for more data, BUT I WILL WAIT INDEFINITELY!!! */
} else {
/* Handle error */
}
} else {
/* EOF, OK, Process received data */
}
}
The problem arises when the first recv call retrieves the entire message, but subsequent calls result in errno == EAGAIN, leading to an indefinite wait for more data that will never arrive.
As per this answer
this behavior is expected.
My question is:
How can I reliably determine that I have received the entire message if the second call to recv won’t give me EOF but instead returns EAGAIN, leaving me waiting indefinitely?
>Solution :
How can I reliably determine that I have received the entire message …
TCP has no concept of a message, it is only a byte stream. This means to determine the end of the message you need first to understand what a message is in terms of the application protocol, like for example a line ending with \n, a fixed size message or some payload prefixed by its size. Based on this then you can check if the data received so far represent only part of the message, the full message or even more than one message.