四次挥手过程
假设客户端主动关闭连接
第一次握手:客户端发送FIN报文,进入FIN-WAIT-1状态,等待服务器的ACK报文
第二次握手:服务器确认客户端的FIN报文
第三次握手:客户端收到ACK后进入FIN-WAIT-2状态(发送功能关闭,接收功能还开启),等待服务器发送剩下的数据或等待服务器的FIN报文
第四次握手:客户端确认服务器的FIN报文,进入TIME-WAIT状态,等待2MSL(MSL:报文最大生成时间)后关闭连接,服务器收到ACK后关闭连接
为什么要有TIME-WAIT状态
主动发起关闭连接的才有TIME-WAIT状态
1.确保对方能正常的关闭连接:客户端发送ACK报文后进入TIME-WAIT状态,如果ACK报文没有按时到达服务器端,就会引起服务器超时重传FIN报文,如果没有TIME—WAIT状态则服务器没办法知道FIN报文能否正确到达客户端,TIME-WAIT是为了确保服务器能正常的关闭连接
2.防止历史连接的报文被后面相同的四元组接收:如果没有TIME-WAIT状态,客户端在关闭连接后开启相同的四元组的tcp连接,上次连接中被延迟的报文到达时,有可能被新的连接接收,引起不必要的错误。(你可能想到了有序号,但是序号不是无限增长的,会发生回绕为初始值的情况,这意味着无法根据序列号来判断新老数据)
为什么TIME-WAIT状态是2MSL
MSL是报文最长生存时间,2MSL是相当于允许报文丢失一次。若 ACK 在一个 MSL 内丢失,被动方就会重发FIN报文,FIN报文会在第二个MSL内到达
小知识:Linux中的TIME-WAIT时间是60秒,则一个MSL为30秒