什么是四次挥手
TCP建立连接时候,双方总共会发送3个包,以确保连接建立成功。称之为三次握手。同样的,TCP断开连接时候,双方总共会发送4个包,以确保连接正常断开。而这个过程,称之为四次挥手或四次断开。
四次挥手过程
以客户端主动断开为例进行说明。如图,是我找到的四次挥手示意图:

第一次挥手时,客户端首先发送一个标志位FIN=1的报文,告诉对方,我已经没有数据要发送了,准备断开连接了。发送完该报文后,客户端便等待对方返回确认信息。从发送到接收到对方确认信息的这段时间,客户端状态统称为FIN_WAIT_1。
服务端收到报文后,通过标志位FIN=1判断出来这是一条请求断开连接的报文。随后,服务端便发送一个确认报文,ACK=1。发送后,服务端进入CLOSE_WAIT(关闭等待)状态。而客户端在接收到确认报文后,便进入FIN_WAIT_2状态,等待服务端断开连接。这个过程便是第二次挥手。
注意,此时服务端仍能正常发送数据,客户端仍能正常接收。因为从第一次挥手到现在,只是客户端到服务端的单向连接中断了,服务端到客户端的连接还正常维持,所以客户端还能接受到数据。那什么时候接收不到数据呢?是第三次握手时候。
服务端在第二次握手后,如果还有数据没发送完会继续发送,如果发送完了,可以断开连接了,便会发送一个断开连接的报文,即FIN=1。此后,服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。这个过程就是第三次挥手。
客户端收到服务端请求断开连接的报文后,发送一个确认报文ACK=1作为应答。此时客户端处于TIME_WAIT(时间等待)状态,并在这个状态下等待2MSL时长。这个过程称为第四次握手。
最后,服务端收到从客户端发出的确认报文之后结束 LAST-ACK 阶段,进入 CLOSED 阶段。客户端等待完 2MSL之后,结束 TIME-WAIT 阶段,进入 CLOSED 阶段,由此完成四次挥手。
为什么最后要等待MSL
MSL全称为Maximum Segment Lifetime,最大报文生存时间,意思就是一个TCP报文在网络中最大的存活时间,超过这个时间,包就会被网络丢弃掉。一个MSL时间大约60s,不同系统可能不一样。那为啥最后客户端还要等等2MSL呢?为啥不是1MSL?为啥不能立即断开?
正常情况下,第三次挥手时,服务端发送一个FIN报文,然后等待客户端确认。客户端收到后发送确认报文,服务端收到这个确认报文后,流程结束。到这里是没有问题的。但现实网络情况复杂,如果服务端没有收到确认报文,它是会重新发送FIN报文的。
假设客户端发送最后一次确认报文后就立即断开,但受网络影响,服务端重新发送了一个FIN报文。此时FIN抵达客户端后,发现没有对应的连接了,这时候客户端的内核会直接回复一个RST给服务端,强制断开连接,服务端异常报错。显然这种立即断开机制不合理,需要确认服务端接收确认报文后再断开。
假设客户端发送最后一次确认报文后没有立即断开,等了一段时间。此时收到了服务端重传的FIN,由于客户端没有断开连接,依然持有这条连接的四元组,收到重传 FIN 后,便可以重新补发 ACK 给服务端。完成闭环,没有问题。
既然要等待一段时间,那这个时间是多次呢?