四次挥手过程
图片来自公众号:小林coding
第一次挥手:客户端要关闭连接时,向服务端发送一个FIN报文,FIN位置为1,此时客户端没有数据要发送了,客户端进入FIN_WAIT_1状态。
第二次挥手:服务端收到报文后,向客户端发送ACK报文,服务端进入CLOSE_WAIT。
第三次挥手:服务端在断开连接前可能还有数据要处理,在处理完数据后向客户端发送FIN报文,服务端没有要处理的数据了,进入FIN_WAIT_2状态。
第四次挥手:客户端收到服务端的FIN后向客户端发送一个ACK报文,进入TIME_WAIT状态,服务端收到后进入CLOSED状态,关闭了连接。而客户端在经过2MSL后一小段时间后,进入CLOSED状态,关闭连接。
为什么需要四次挥手
因为在服务端响应客户端的FIN时,只发送了ACK包,为什么只发送ACK包呢,因为在接收到客户端的FIN时,服务端可能还有数据没有处理完,所以只能先回应,FIN包要处理完数据以后才能发出。
TIME_WAIT和MSL
MSL是报文在网络中的最大生存时间。如果服务端没有收到客户端的ACK报文的话会继续发送FIN报文。发送报文和等待报文传回来的时间是2MSL,客户端TIME——WAIT的2MSL是在收到服务端的FIN后开始计时的。TIME_WAIT时间内如果没有再次收到服务端的FIN报文的话说明ACK报文已经被服务端接收到了服务端进入CLOSED状态,所以,TIME_WAIT保证了服务端能够正常关闭。
TIME_WAIT另一个作用是保证旧连接的数据包不会被新连接的接收:如果没有TIME_WAIT或时间太短的话,服务端发送的旧的数据包可能还在网络中,而同一个客户端和服务端可能在之后又在同一端口建立了连接,也就是四元组相同的连接,那么客户端有可能会正常地接收这个连接,导致数据异常。