tcp在TIME_WAIT状态下等待2MSL

第一,为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。 
第二,A在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。 


 

1 TCP关闭时的四次握手
Tcp连接在关闭的的时候,执行的是一个四次握手的过程,下图是客户端发起的关闭时客户端和服务器的状态转换图
 
具体过程如下:
1、 客户端发送FIN报文段,进入FIN_WAIT_1状态。
2、 服务器端收到FIN报文段,发送ACK表示确认,进入CLOSE_WAIT状态。
3、 客户端收到FIN的确认报文段,进入FIN_WAIT_2状态。
4、 服务器端发送FIN报文端,进入LAST_ACK状态。
5、 客户端收到FIN报文端,发送FIN的ACK,同时进入TIME_WAIT状态,启动TIME_WAIT定时器,超时时间设为2MSL。
6、 服务器端收到FIN的ACK,进入CLOSED状态。
7、 客户端在2MSL时间内没收到对端的任何响应,TIME_WAIT超时,进入CLOSED状态。
client在发出server 端fin的ack以后,进入了time_wait的状态,知道2MSL以后,才会关闭。先来解释下2MSL,max segment lifetime,最大生成时间。MSL的值在一般的实现中取30s,有些实现采用2分钟。在TCP的状态机中的“被动关闭”,从CLOSE_WAIT到 LAST_ACK中有一个如下的规则:当T C P执行一个主动关闭,并发回最后一个A CK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失。个规则导致一个后果就是在 这个2MSL的时间内,该地址上的链接(客户端地址、端口和服务器端的地址、端口)不能被使用。比如我们在建立一个链接后关闭链接然后迅速重启链接,那么 就会出现端口不可用的情况。
2 time_wait状态的必要性

如果不考虑报文延迟、丢失,确认延迟、丢失等情况,TIME_WAIT的确没有存在的必要。当网络在不理想的情况下通常会有报文的丢失延迟发生,让我们看下面的一个特例:
客户端进入发送收到四次握手关闭的最后一个ACK后,进入TIME_WAIT同时发送ACK,如果其不停留2MSL时间,而是马上关闭连接,销毁连接上的资源,当发送如下情况时,将不能正常的完成四次握手关闭:
客户端发送的ACK在网路上丢失,这样服务器端收不到最后的ACK,重传定时器超时,将重传FIN到客户端,由于客户端关于该连接的所有资源都释放,收到重传的FIN后,它没有关于这个FIN的任何信息,所以向服务器端发送一个RST报文端,服务器端收到RST后,认为搞连接出现了异常(而非正常关闭)。
所以,在TIME_WAIT状态下等待2MSL时间端,是为了能够正确处理第一个ACK(最长生存时间为MSL)丢失的情况下,能够收到对端重传的FIN(最长生存时间为MSL),然后重传ACK。
是否只要主动关闭方在TIME_WAIT状态下停留2MSL,四次握手关闭就一定正常完成呢?
答案是否定的?可以考虑如下的情况,
 
TIME_WAIT状态下发送的ACK丢失,LAST_ACK时刻设定的重传定时器超时,发送重传的FIN,很不幸,这个FIN也丢失,主动关闭方在TIME_WAIT状态等待2MSL没收到任何报文段,进入CLOSED状态,当此时被动关闭方并没有收到最后的ACK。所以即使要主动关闭方在TIME_WAIT状态下停留2MSL,也不一定表示四次握手关闭就一定正常完成。
结论:在TIME_WAIT下等待2MSL,只是为了尽最大努力保证四次握手正常关闭。确保老的报文段在网络中消失,不会影响新建立的连接
考虑如下的情况,主动关闭方在TIME_WAIT状态下发送的ACK由于网络延迟的原因没有按时到底(但并没有超过MSL的时间),导致被动关闭方重传FIN,在FIN重传后,延迟的ACK到达,被动关闭方进入CLOSED状态,如果主动关闭方在TIME_WAIT状态下发送ACK后马上进入CLOSED状态(也就是没有等待)2MSL时间,则上述的连接已不存在:现在考虑下面的情况,假设上述的链接的四元组为(192.201.0.80:23,192.201.0.85:5555),由于连接已关闭,我们可以马上建立一个新的连接,并且这个连接的四元组也是(192.201.0.80:23,192.201.0.85:5555),那么当上一个连接的重传FIN到达主动关闭方时,被新的连接所接受,这将导致新的连接被复位,很显然,这不是我们希望看到的事情。
新的连接要建立,必须是在主动关闭方和被动关闭方都进入到CLOSED状态之后才有可能。所以,最有可能导致旧的报文段影响新的连接的情况是:
在TIME_WAIT状态之前,主动关闭方发送的报文端在网络中延迟,但是TIME_WAIT设定为2MSL时,这些报文端必然会在网络中消失(最大生存时间为MSL)。被动关闭方最有可能影响新连接的报文段就是我们上面讨论的情况,对方ACK延迟到达,在此之前重传的FIN,这个报文端发送之后,TIME_WAIT的定时器超时时间肯定大于MSL,在1MSL时间内,这个FIN要么在网络中因为生成时间到达而消失,要么到达主动关闭方被这确的处理,不会影响新建立的连接。

 

什么是2MSL

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即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值