TCP Four-way Handshake
4-way handshaking is the process of terminating a connection between two devices in TCP. It involves four steps:
- The active device (client) sends a
FIN(finish) packet to the passive device (server) to initiate the termination process. - The passive device responds with an
ACKpacket to acknowledge the FIN packet. - The passive device sends its own
FINpacket to initiate termination on its end. - The active device responds with an
ACKpacket to acknowledge the passive device’sFINpacket.
This completes the 4-way handshake and the connection is terminated.
刚开始双方都处于 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=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
第四次挥手
- 客户端收到
FIN之后,一样发送一个ACK报文作为应答,且把服务端的序列号值 +1 作为自己ACK报文的序列号值,此时客户端处于TIME_WAIT状态。需要过一阵子以确保服务端收到自己的ACK报文之后才会进入CLOSED状态,服务端收到ACK报文之后,就处于关闭连接了,处于CLOSED状态。 - 即客户端收到服务端的连接释放报文段后,对此发出确认报文段(
ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
为什么需要四次挥手呢?
当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN-ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。
但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送,故需要四次挥手。