网络编程(25)—— 详解TCPIP断开连接后的Time-wait状态

     之前在socket选项之SO_REUSEADDRTCP_NODELAY一文中简单介绍过断开连接的一方套接字进入的Time-wait状态。现在我们详细的讨论该状态,以解决下面疑问:

        1、 Time-wait状态是怎么产生的?

        2、客户端在断开连接后会进入Time-wait状态吗?

        3Time-wait状态有什么用?

        4Time-wait状态下的端口号能否设置被其他套接字重新使用?

Time-wait状态是怎么产生的?

    首先,第一个问题,Time-wait状态是怎么产生的?在解决这个问题之前我们先简单回顾下TCP连接在断开时的四次握手过程:

 

    图中演示了从主机A主动发起断开连接请求的四次握手过程:

    第一次握手:主机A发送FIN数据包,SEQ设置为5000,表示主机B在接收到数据后需要返回一个ACK5001的数据包,否则主机A重新发送该数据包。

 

    第二次握手:主机B发送ACK5001的数据包表示成功接收主机A断开连接请求,同时SEQ6000,但是这是断开连接的过程,主机B不会期望主机A返回ACK6001的数据包。

 

    第三次握手:主机B准备好了断开连接工作后,向主机A发送FIN数据包,表示请求断开与A的连接,同时SEQ设置为6001ACK设置为5001

 

    第四次握手:主机A接收到主机B请求断开连接的数据包之后返回允许断开连接的数据包,SEQ设置为5001,同时ACK设置为6002表示已经成功接收主机B发送的数据包。

       我们所讨论的Time-wait状态就是发生在主机A返回最后一个数据包之后,如下图所示,当主机A的套接字进入Time-wait状态后,该套接字绑定的端口号将在这段时间内不能被其他套接字使用,这就是当我们使用Ctrl+C结束服务端程序后,马上再使用该端口启动服务端时会出现bind  error的原因(Ctrl+C虽然是强制关闭服务器端,但是断开TCP的连接时也会经历上述四个握手过程)。

 

 

客户端在断开连接后会进入Time-wait状态吗?

    在验证这个问题之前,先给出这个问题的答案!答案就是:会。只不过客户端的端口号是随机分配的所以我们很少见到bind error的错误,下面我将通过netstat命令验证这个答案。

    第一步,使用系统的9190端口启动服务端程序。     

    [Hyman@Hyman-PC echoSever]$ ./serv 9190

    服务端进入阻塞等待连接状态,然后用netstat –ant命令查看目前系统中socket的状态。

 

    请注意红色圈出的部分,就是服务端创建的socket,目前已经进入listen状态。

       第二步,使用客户端连接服务器。

      

  [Hyman@Hyman-PC echoSever]$ ./clnt 127.0.0.1 9190
  connect succeed

    客户端连接成功,然后再使用netstat –ant命令查看目前系统的socket的状态:


    服务端的套接字进入established状态,同时出现了客户端的套接字,绑定的端口为43436,也进入了established状态。

    第三步,输入Ctrl+C断开客户端的连接,然后用netstat–ant观察套接字的状态

       

    发现客户端的socket进入了TIME_WAIT状态,而此时如果我们对43436端口进行bind就会出现bind错误:

       

    [Hyman@Hyman-PC echoSever]$ ./serv 43436
     bind error

Time-wait状态有什么用?

    之所以设置Time-wait状态,主要是考虑:万一由主机A发送的最后一次握手的数据包丢失时,主机B会再次发送第三次握手的数据包,若此时主机A关闭了Socket就会出现主机B永远等不到主机A最后一次握手数据包的情况,B也就永远无法关闭。所以在主动发起断开连接请求的主机上设置了这个Time-wait状态。

Time-wait状态下的端口号能否设置被其他套接字重新使用?

    这就是《socket选项之SO_REUSEADDRTCP_NODELAY》一文中提到的方法,通过socket可选项设置函数setsockopt(…)可以实现设置套接字Time-wait状态的开启和关闭。

int option;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)option,sizeof(option));
…

    设置option1时可以将Time-wait状态下套接字的端口重新分配给新的套接字。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值