共计 1120 个字符,预计需要花费 3 分钟才能阅读完成。
2MSL TIME_WAIT状态存在的理由
1、让4次握手关闭流程更加可靠;
4次握手的最后一个ACK是是由主动关闭方发送出去的,若这个ACK丢失,被动关闭方会再次发一个FIN过来。若主动关闭方能够保持一个2MSL的TIME_WAIT状态,则有更大的机会让丢失的ACK被再次发送出去。
2、防止lost duplicate对后续新建正常链接的传输造成破坏。
Linux中是无法修改tcp的TIME_WAIT值的,除非重新编译,起码我是没有找到怎么改。值得注意的是,net.ipv4.tcp_fin_timeout这个参数是FIN_WAIT_2的值,而不是TIME_WAIT的值。
TIME_WAIT的作用
TCP初见于互联网早期,当时的网络很不稳定,大量的丢包,为了冗余,大量包复制多径传输,网速慢–正因为如此,TCP才会更有意义。为了保证TCP的严格语义,就要避免上述冗余机制以及网速慢导致的问题,这些问题集中体现在连接关闭时的四次挥手上。
由于TCP是全双工的,因此关闭连接必须在两个方向上分别进行。首先发起关闭的一方为主动关闭方,另一方为被动关闭方。很多人都会在这里晕掉,实际上四次挥手比三次握手还简单。四次挥手简单地分为三个过程:
过程一.主动关闭方发送FIN,被动关闭方收到后发送该FIN的ACK;
过程二.被动关闭方发送FIN,主动关闭方收到后发送该FIN的ACK;
过程三.被动关闭方收到ACK
以上三步下来,圆圈就闭合了!也就是说,在过程三后,被动关闭方就可以100%确认连接已经关闭,因此它便可以直接进入CLOSE状态了,然而主动关闭的一方,它无法确定最后的那个发给被动关闭方的ACK是否已经被收到,据TCP协议规范,不对ACK进行ACK,因此它不可能再收到被动关闭方的任何数据了,因此在这里就陷入了僵局,TCP连接的主动关闭方如何来保证圆圈的闭合?
这里,协议外的东西起作用了,和STP(Spanning tree)依靠各类超时值来收敛一样,IP也有一个超时值,即MSL,这类超时值超级重要,因为它们给出了一个物理意义上的不可逾越的界限,它们是自洽协议的唯一外部输入。MSL表明这是IP报文在地球上存活的最长时间,如果在火星上,Linux的代码必须要重新定义MSL的值并且要重新编译。于是问题就解决了,主动关闭一方等待MSL时间再释放连接,这个状态就是TIME_WAIT。对于被动关闭的一方,发出FIN之后就处在了LAST_ACK状态了,既然已经发出FIN了,缺的无非也就是个ACK,连接本身其实已经关闭了,因此被动关闭的一方就没有TIME_WAIT状态。
实际上,两倍MSL才能说明一个报文的彻底丢失,因为还要记入其ACK返回时的MSL。