zoukankan      html  css  js  c++  java
  • tcp三次握手和四次挥手

    最近发现服务器的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对于我们来说往往是有利的。

  • 相关阅读:
    ubuntu shell插件
    通过更改服务器解决双系统ubuntu时间+8
    ubuntu安装mysql遇到的问题
    05 面向对象:构造方法&static&继承&方法 &final
    electron 大体结构
    js时间Date对象介绍及解决getTime转换为8点的问题
    Fiddler命令行和HTTP断点调试
    使用HTTP头去绕过WAF(bypasswaf)
    Linux下php5.3.3安装mcrypt扩展
    Error: Cannot find a valid baseurl for repo: epel
  • 原文地址:https://www.cnblogs.com/agostop/p/2708534.html
Copyright © 2011-2022 走看看