time_wait状态

来源:互联网 发布:最好看的韩国r级 知乎 编辑:程序博客网 时间:2024/06/06 19:10

   我们在将这个服务器关闭之后,立刻重新启动,会启动错误,错误信息提示为:该地址已被占用。但是奇怪的是,刚刚这个服务器明明就已经关闭了啊,为什么还会被提醒IP地址被占用呢?

   这是因为在tcp连接中存在着一个time_wait状态(详情请看unix 网络编程 卷1第三版37页),time_wait状态存在于主动断开连接的那一端(服务器或者客户端)。

   time_wait状态存在主要有两个原因:

   一:大家试想一下,在tcp断开连接的四次握手的时候(最后一次握手时),如果服务器给客户端发送一个断开连接的FIN包,假如客户端收到这个包以后还要发送确认ack包给服务器,等服务器收到之后,连接才会彻底断开。

   现在假设一种情况,客户端收到FIN包以后,向服务器发送的ACK包,服务器没有收到。这时作为服务器而言,他没有收到客户端的确认ACK包,它肯定以为是自己发送的FIN包在传输过程中丢失了,它会再次发送FIN包,此时由于客户端处在time_wait状态,当它再次收到FIN包的时候,就能知道这是服务器第二次发送的FIN包(假设客户端没有time_wait状态,在发完ACK包以后就直接进入下一个状态,那么它是无法识别这个FIN包的,记住,在什么状态识别什么样的包),所以time_wait状态就是为了防止出现这中情况。

          二:大家在试想一下,如果没有time_wait状态,假如服务器在给客户端发送数据,结果由于各种原因(路由循环,阻塞等等),导致某个包客户端没有收到,这时服务器重发了一次,客户端收到了这个包,然后通信结束了,双方都关闭连接了(注意:此时这个包还在网络中路由呢)。后来你又重启了这个服务器和这个客户端,假如没有time_wait状态,你就重启成功了(但实际上,你很有可能重启失败,因为提示地址被占用),假设重启成功,那么刚好在网络上的先前的那个包找到了你这个客户端,把这个包给你,但是我们知道,这是上一次通信的数据包,我们根本就不能接收。所以time_wait就又发挥作用了,它使得你的服务器或者客户端无法启动,这样经过一段时间后才能启动,那先前的那个包早就“死亡”了(因为我们知道每个包都有自己的生存时间,即跳数),这样我们重新打开的客户端和服务器(和上一个同样的IP和端口)就不会收到上一次的数据报了。


       最后,声明一下,本人编程知识和网络知识才刚刚起步,我只是将自己理解的说的更通俗一点而已,如果大家有不同意见或者我有说错的地方都欢迎大家指出。

原创粉丝点击