ITPub博客

首页 > Linux操作系统 > Linux操作系统 > tcp/ip四次挥手一篇不错的文章

tcp/ip四次挥手一篇不错的文章

Linux操作系统 作者:HaFoLuoKe 时间:2013-11-12 21:34:33 0 删除 编辑

最近发现服务器的time_wait状态很多,很是不解,网上找了些文章看了看,总结了一下:

 

建立连接:
1、C发送SYN到S,并且C进入SYN_SEND状态
2、S收到C的SYN,同时发送ACK确认包和自己的SYN包给C
3、C收到S的SYN+ACK,向服务器B发送确认ACK
数据传输开始。

断开连接:
1、客户端C发送一个FIN,用来关闭C到S的数据传送,C进入FIN_WAIT_1状态
2、S收到这个FIN后,进入CLOSE_WAIT(此时是被动关闭),然后发送ACK确认到C,这时C到S的数据链路关闭,C此时进入TIME_WAIT_2。
3、S等待发送到C的数据发送完成后,发送FIN到C,此刻S状态转换为LAST_ACK,并等待C的ACK到来。
4、C收到S的FIN,将状态转换为TIME_WAIT,并发送ACK到S,S收到ACK后,状态改变为CLOSED。

在断开时,假设最后一个ACK丢失了,服务器会重发它发送的最后一个FIN,所以客户端必须维持一个状态信息,以便能够重发ACK;如果不维持这种状态,客户端在接收到FIN后将会响应一个RST,服务器端接收到RST后会认为这是一个错误。如果TCP协议能够正常完成必要的操作而终止双方的数据流传输,就必须完全正确的传输四次握手的四个节,不能有任何的丢失。这就是为什么socket在关闭后,仍然处于 TIME_WAIT状态,因为他要等待以便重发ACK。
如果目前连接的通信双方都已经调用了close(),假定双方都到达CLOSED状态,而没有TIME_WAIT状态时,就会出现如下的情况。现在有一个新的连接被建立起来,使用的IP地址与端口与先前的完全相同,后建立的连接又称作是原先连接的一个化身。还假定原先的连接中有数据报残存于网络之中,这样新的连接收到的数据报中有可能是先前连接的数据报。为了防止这一点,TCP不允许从处于TIME_WAIT状态的socket建立一个连接。处于TIME_WAIT状态的socket在等待两倍的MSL时间以后(之所以是两倍的MSL,是由于MSL是一个数据报在网络中单向发出到认定丢失的时间,一个数据报有可能在发送图中或是其响应过程中成为残余数据报,确认一个数据报及其响应的丢弃的需要两倍的MSL),将会转变为CLOSED状态。这就意味着,一个成功建立的连接,必然使得先前网络中残余的数据报都丢失了。 
由于TIME_WAIT状态所带来的相关问题,我们可以通过设置SO_LINGER标志来避免socket进入TIME_WAIT状态,这可以通过发送RST而取代正常的TCP四次握手的终止方式。但这并不是一个很好的主意,TIME_WAIT对于我们来说往往是有利的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26899445/viewspace-776439/,如需转载,请注明出处,否则将追究法律责任。

上一篇: Java反射
下一篇: 2013-11-28
请登录后发表评论 登录
全部评论

注册时间:2013-03-12

  • 博文量
    31
  • 访问量
    44651