TCP Four-way Handshake

4-way handshaking is the process of terminating a connection between two devices in TCP. It involves four steps:

  1. The active device (client) sends a FIN (finish) packet to the passive device (server) to initiate the termination process.
  2. The passive device responds with an ACK packet to acknowledge the FIN packet.
  3. The passive device sends its own FIN packet to initiate termination on its end.
  4. The active device responds with an ACK packet to acknowledge the passive device’s FIN packet.

This completes the 4-way handshake and the connection is terminated.

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a4190d0d324b427cb63154d3f84e47bc~tplv-k3u1fbpfcp-watermark.awebp

刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:

第一次挥手
  • 客户端会发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
  • 即发出连接释放报文段(FIN=1,序号 seq=u),并停止再发送数据,主动关闭TCP连接,进入 FIN_WAIT1(终止等待1)状态,等待服务端的确认。
第二次挥手
  • 服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
  • 即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号 ack=u+1,序号 seq=v),服务端进入 CLOSE_WAIT(关闭等待)状态,此时的 TCP 处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入 FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
第三次挥手
  • 如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
  • 即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1ACK=1,序号 seq=w,确认号 ack=u+1),服务端进入 LAST_ACK(最后确认)状态,等待客户端的确认。
第四次挥手
  • 客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
  • 即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1seq=u+1ack=w+1),客户端进入 TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入 CLOSED 状态。

为什么需要四次挥手呢?

当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN-ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。

但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送,故需要四次挥手。