tags:

views:

51

answers:

2

In TCP socket programming, if recv() returns 0, it is taken as an indication that the other side closed its connection. However, AFAIK, the TCP RFC does not mandate the payload of TCP to be > 0. So, theoretically, a TCP stack can receive a message with payload 0.

So, essentially my question is what will recv() returns if it receives a packet of payload sized 0? If it returns 0, then how do we distinguish it from a closed connection indication.

+2  A: 

Right, according to POSIX if recv returns 0, then the connection is shut down correctly by the peer.

If someone has managed to send a TCP packet with a zero-sized payload, then the OS doesn't have to return any data to the process being blocked on recv system call on that socket.

Remember that TCP payloads form a continuous stream that may be randomly sliced by the OS, not a sequence of datagrams that must be returned during a single system call.

Andrey Vlasovskikh
+3  A: 

TCP segments with a payload size of 0 are ubiquitous - they occur in pretty much every real-world TCP stream. They're sent whenever one side wishes to acknowledge reciept of data from the other, but has no data to send of its own. (These are commonly known as "ACK packets", but an "ACK packet" is just a regular segment that happens to contain no data).

Since such packets do not contain any data to deliver to the user application, they will not cause recv() to return - recv() will continue blocking until some actual data arrives. If recv() returns 0, then it is a definite indication that the other end has closed its side of the connection and won't be sending any more data.

Remember that TCP is stream-oriented: there is not a 1-to-1 mapping between the data returned by a single recv() call and the data in a single TCP segment. A single recv() call might return a block of data that overlaps several TCP segments, and the data in a single TCP segment might be returned in multiple recv() calls. The boundaries between TCP segments are not visible to the application using the BSD sockets API. If you want such boundaries, you need to either implement yourself using an application-layer protocol within the TCP stream, or use a datagram-oriented protocol like UDP.

caf
+1 for mentioning ACKs.
Andrey Vlasovskikh