Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What value will recv() return if it receives a valid TCP packet with payload sized 0

Tags:

tcp

recv

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.

like image 331
Aditya Sehgal Avatar asked Jul 07 '10 19:07

Aditya Sehgal


People also ask

What does recv () return?

RETURN VALUE Upon successful completion, recv() shall return the length of the message in bytes. If no messages are available to be received and the peer has performed an orderly shutdown, recv() shall return 0. Otherwise, -1 shall be returned and errno set to indicate the error.

What is returned by recv () from the server after it is done sending the HTTP request?

If successful, recv() returns the length of the message or datagram in bytes. The value 0 indicates the connection is closed. If unsuccessful, recv() returns -1 and sets errno to one of the following values: Error Code.

Is recv blocking calls?

recv(IPC, Buffer, int n) is a blocking call, that is, if data is available it writes it to the buffer and immediately returns true, and if no data is available it waits for at least n seconds to receive any data.

How many sockets does TCP server process has at the time of serving single client?

So the answer to your question is that only one listen socket is needed, but new sockets will be created as clients connect (and removed as they disconnect).


1 Answers

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.

like image 177
caf Avatar answered Sep 28 '22 05:09

caf