HelloBug0

1 状态迁移

以下是TCP连接状态迁移图:

连接迁移

主动关闭连接的一方(客户端和服务端都可以主动关闭连接)在收到被动关闭连接的一方发来的FIN包并发送ACK之后,会进入 TIME_WAIT 状态,并且在等待 2MSL 之后,连接状态进入 CLOSED 状态。

2 什么是MSL?

MSL(Maxinum Segment Lifetime)报文最大生存时间,TCP连接中,发往对端的报文最大生存时间,即经过该时间之后,可以认为报文不复存在。

3 为什么TIME_WAIT状态的报文等待2MSL?

等待2MSL是为了保证TCP连接断开时,被动关闭方能正确关闭连接,以及防止新旧连接的数据包发生混淆。

之所以是2MSL,而不是1MSL,因为需要保证最后一个ACK能到达对端,以及等待对端因未收到ACK而可能重传的FIN报文。

4 如何保证被动关闭方关闭连接?

主动关闭方我们称之为A方,被动关闭方我们称之为B方。

  1. A方主动关闭连接,发送FIN报文给B方;B方收到FIN报文之后,发送ACK给A方;B方发送FIN报文给A方,A方收到FIN报文之后,发送ACK(记为ACK1)给B方,,然后进入TIME_WAIT状态,设置时长为2MSL的定时器,如果定时器到期会进入CLOSED状态。
  2. A方发送的ACK报文中途丢了,B方在等待ACK超时之后,再次发送FIN报文
  3. 由于A方处于TIME_WAIT状态,收到重复的FIN报文之后,知道之前响应的ACK丢了,于是再次发送一个ACK(记为ACK2)给B方,此时重置定时器,重新计时
  4. B方收到ACK2,四次挥手完成,B方的连接状态进入CLOSED状态
  5. A方在等待2MSL时间之后,连接状态进入CLOSED状态
  6. 双方关闭连接完成

根据以上过程可知,主动关闭方主动等待2MSL,主要为了防止其发送的对FIN包的ACK包响应可以通知到被动关闭方,保证被动关闭方关闭连接。

5 如何保证当前连接中所有报文失效?

以下是控制连接断开的相关参数。

我们知道FIN包重发的超时时间遵循指数避让原则,也就是说最后一个FIN包的重发时间间隔只要不超过2MSL,连接就能正常断开。通过设置FIN包合理的重试次数,以及MSL的时间,可以保证在2MSL时间内,当前连接中的所有报文失效。