速览

MSL: Maximun Segment Lifetime,即报文最大生存时间 注意:超过这个时间,报文将被丢弃!(确保旧tcp连接中链路中所有旧报文被丢弃) 2MSL一般为4分钟!

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
2MSL有多长? - 图1
2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间!
等待2MSL的目的:

在上图情景下解析,客户端主动发起关闭连接

  1. 在服务端未收到ACK(第三次握手)超时后,再次发送FIN报文,客户端接到重发的FIN报文,可再次发送ACK。
  2. 防止已经断开的连接1在链路中残留的FIN包终止掉新的连接(该连接重用五元组)【发生概率低,但由于seq循环重用,也是有可能的】
  3. 防止链路上已经关闭的连接残余数据包干扰正常的数据包造成数据流不正常!

在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。

假设主动关闭方无TIME-WAIT状态会发生什么?

若主动关闭方不进入TIME-WAIT,且最后一个 ACK接收失败,那么被动关闭方会重传FIN包。由于该连接在主动关闭方已认为关闭,无法识别该FIN包。协议栈会认为对端疯了,还没建立连接你给我来个FIN?
于是回复一个RST包给对端,被动关闭方就收到一个错误(connection reset by peer

Broken pipe: 收到RST后,还继续往该连接写数据,会触发broken pipe 错误!