TCP 半关闭

参考close-vs-shutdown-socket

with shutdown, you will still be able to receive pending data the peer already sent

  • even if you close a tcp socket, it won't necessarily be immediately reusable anyway, since it will be in a TIME_WAIT state while the OS makes sure there's no outstanding packets that might get confused (socket option : resue port, resue address)

  • if socket shared by other processes, a shutdown affects all copies of the sockets while close affects only the file descriptor in on process.

TCP关闭

standard TCP connection gets terminated by 4-way finalization:

  • Once a participant has no more data to send, it sends a FIN packet to the other

  • The other party returns an ACK for the FIN.

  • When the other party also finished data transfer, it sends another FIN packet

  • The initial participant returns an ACK and finalizes transfer.

However, there is another "emergent" way to close a TCP connection(紧急关闭):

  • A participant sends an RST packet and abandons the connection
  • The other side receives an RST and then abandon the connection as well

shutdown

shutdown(wr) sends a FIN packet to the other end. the other end Receivewill get 0 size.tcp的read返回0表示对面主动关闭了socket。

until the other party send you the FIN packet you are still able receive data. 在调用shutdown(wr)后你还是可以从对面收到数据。

close will send fin packet and destroy fd immediately when socket is not shared with other processes

shutdown SHUT_RD, process can still recv data from the socket, but recv will return 0 if TCP buffer is empty.After peer send more data, recv will return data again(linux only: after shutdown rd when peer send data recv will return data again).

shutdown SHUT_WR will send fin packet to indicate the Further sends are disallowed. the peer can recv data but it will recv 0 if its TCP buffer is empty

shutdown SHUT_RDWR (equal to use both SHUT_RD and SHUT_WR) will send rst packet if peer send more data.

状态图

tcp-status