TCP四次挥手后的TIME_WAIT状态

来源:互联网 发布:秘鲁地震预警软件 编辑:程序博客网 时间:2024/05/16 17:12

首先查看TCP建立连接与断开连接的两对端的状态图,如下:
这里写图片描述
由图可知客户端在收到服务端的请求断开连接带有的FIN位结束报文段,并发送ACK确认以后,其并没有直接关闭,进入到CLOSED状态,而是转变为TIME_WAIT状态。

  1. TIME_WAIT状态是做什么的?
    在这个状态,顾名思义,即客户端连接要等待一段长为2MSL(报文段最大生存时间)的时间,才能关闭连接,在标准文档RFC 1122的MSL建议值为2min.
  2. 为什么存在此状态?
    (1)可靠的终止TCP的连接:即如上图,最后客户端确认服务器结束报文段6的ACK报文段7若传输中丢失,服务器没收到确认报文段,则会重发结束报文段,因此客户端需要停留在此状态以处理重复收到的结束报文段,从而向服务器发送确认报文段。若客户端此时已经变为closed状态,它则会以复位报文段来回复服务器,服务器则会认为这是一个错误。
    (2)保证让迟来的报文段有足够的时间被识别丢弃:当一个TCP连接处在TIME_WAIT状态,它则会依然占用当前的端口,新的连接时无法立即使用的,但当没有这个状态,当立即有新的TCP连接时,其会使用与刚才相同的IP地址与端口号,此时这个新的连接则极有可能收到原来连接的迟到的TCP报文段,这明显是不应该发生的,所以设置这个状态是极有必要的。

  3. 为什么TIME_WAIT状态要等待2MSL时间?
    由于TCP报文段最大生存时间为MSL,其保持2MSL时间可以确保网络上两个传输方向的尚未接收到的、迟到的报文段都已经消失,或被路由器丢弃,而2MSL时间后建立新的连接其绝不会收到原来连接的应用程序数据。

但在一些情况下,如:一般一个服务器的IP与端口号是固定的,但若这个服务器主动关闭连接异常终止,我们此时则需要立即重启此服务器,但由于它此时在TIME_WAIT状态则先会占着此IP地址与端口号,导致它会重启失败,而我们要改变这种情况,可用以下函数解决:

int setsockopt(int sockfd,int level,int optname,const void* optval,socklen_t optlen);//可如以下如此调用:int opt=1;setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));  

以上SO_REUSEADDR参数可强制进程立即使用处于TIME_WAIT状态连接占用的端口。

原创粉丝点击