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?
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 you are implementing, 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 represents only part of a message, a full message, or even more than one message.