4

Consider a TCP connection established between two TCP endpoints, where one of them calls either:

  1. close(): Here, no further read or write is permitted.

  2. shutdown(fd, SHUT_WR): This converts the full duplex connection to simplex, where the endpoint invoking SHUT_WR can still read.

However, in both the cases a FIN packet is sent on the wire to the peer endpoint. So the question is, how can the TCP endpoint which receives the FIN distinguish whether the other endpoint has used close() or SHUT_WR, since in the latter scenario it should still be able to send data?

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
Vivek Gupta
  • 213
  • 4
  • 10
  • I guess the answer is: it cannot; it needs to be specified by the protocol. – John Dvorak Jan 12 '13 at 12:05
  • What is you mean by "it needs to be specified by the protocol"? – Vivek Gupta Jan 12 '13 at 12:09
  • Such as, (not a real spec) "If the header `connection:keep-alive` was received by the server, then a half-closed connection should be interpretted as fully closed. Otherwise, the sender is allowed to indicate the end of request by closing his part of the connection." – John Dvorak Jan 12 '13 at 12:13
  • Similarly, if the TCP endpoint does shutdown(fd, SHUT_RD) then there happens on message exchange on the wire. In the absence of any message exchange on the wire then how the peer endpoint knows that the other endpoint can not read data on the connection and should stop sending? – Vivek Gupta Jan 12 '13 at 12:25
  • @JanDvorak:Header connection:keep-alive???? – Cratylus Jan 12 '13 at 12:26
  • possible duplicate of [TCP FIN not sent on doing 'close ()' for a multi-threaded TCP client](http://stackoverflow.com/questions/14293254/tcp-fin-not-sent-on-doing-close-for-a-multi-threaded-tcp-client) – Flexo Jan 12 '13 at 12:27
  • 1
    @VivekGupta:`However, in both the cases FIN is sent on the wire to the peer endpoint.` How do you know this? – Cratylus Jan 12 '13 at 12:29
  • I have simulated this scenario and can see FIN being sent in the packet capture. – Vivek Gupta Jan 12 '13 at 12:30

1 Answers1

2

Basically, the answer is, it doesn't. Or, rather, the only general way to find out is to try to send some data and see if you get an ACK or an RST in response.

Of course, the application protocol might provide some mechanism for one side of the connection to indicate in advance that it no longer wants to receive any more data. But TCP itself doesn't provide any such mechanism.

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
  • should this be taken as deficiency with the TCP handshake mechanism? – Vivek Gupta Jan 12 '13 at 12:34
  • 1
    It's only a deficiency if you think that such a feature would be needed. Generally, it's both easy and good practice to design your application protocol so that such situations (where one side wants to send data but the other side doesn't want to receive it) don't arise in the first place, rather than relying on the underlying transport layer (whether it's TCP or something else) to deal with it. – Ilmari Karonen Jan 12 '13 at 12:39