精华内容
下载资源
问答
  • TCP状态图

    千次阅读 2012-07-25 07:18:20
    TCP 共有9 个网路状态,其中涉及到关闭的状态有5 个。  在我们编写网络相关程序的时候,这5 个状态经常出现。因为这5 个状态相互关联,相互纠缠,而且状态变化触发都是由应用触发,但是又涉及操作系统和网络...
     
    

    TCP 共有9 个网路状态,其中涉及到关闭的状态有5 个。

           在我们编写网络相关程序的时候,这5 个状态经常出现。因为这5 个状态相互关联,相互纠缠,而且状态变化触发都是由应用触发,但是又涉及操作系统和网络,所以正确的理解TCP 在关闭时网络状态变化情况,为我们诊断网络中各种问题,快速定位故障有着非常重要的作用和意义。

           为此,我根据W.Richard Stevens 的《TCP/IP 详解》一书,将这5 个状态制成一个时序图(其实原书也有这个图,但不是很好理解),其中黑色字体来表示应用程序行为,红色字体是操作系统行为。

    TCP状态转换图

    =============================================================

    ===========================================================

          深刻理解上面两幅图对于编写基于TCP/IP的应用直观重要,尤其是在链接不正常时,非常有助于定位问题所在

    展开全文
  • TCP状态转换以及TIME_WAIT状态的理解
    感谢作者,讲的特别清晰易懂。
    摘要  TCP/IP状态图 以及 TIME_WAIT作用

    TCP/IP状态图 以及 TIME_WAIT作用

    在TCP/IP状态图中,有很多种的状态,它们之间有的是可以互相转换的,也就是说,从一种状态转到另一种状态,但是这种转换不是随便发送的,是要满足一定的条件。TCP/IP状态图看起来更像是自动机。下图即为TCP/IP状态。

    由上图可以看出,一共有11种不同的状态。这11种状态描述如下:

    CLOSED:关闭状态,没有连接活动或正在进行;

    LISTEN:监听状态,服务器正在等待连接进入;

    SYN_RCVD:收到一个连接请求,尚未确认;

    SYN_SENT:已经发出连接请求,等待确认;

    ESTABLISHED:连接建立,正常数据传输状态;

    FIN_WAIT 1:(主动关闭)已经发送关闭请求,等待确认;

    FIN_WAIT 2:(主动关闭)收到对方关闭确认,等待对方关闭请求;

    TIME_WAIT:完成双向关闭,等待所有分组死掉;

    CLOSING:双方同时尝试关闭,等待对方确认;

    CLOSE_WAIT:(被动关闭)收到对方关闭请求,已经确认;

    LAST_ACK:(被动关闭)等待最后一个关闭确认,并等待所有分组死掉。

    在这11中状态当中,TIME_WAIT这种状态是最重要的,也是最难理解的。

    1.CLOSED:起始点,在超时或者连接关闭时候进入此状态。

    2.LISTEN:服务端在等待连接过来时候的状态,服务端为此要调用socket,bind,listen函数,就能进入此状态。此称为应用程序被动打开(等待客户端来连接)。

    3.SYN_SENT:客户端发起连接,发送SYN给服务器端。如果服务器端不能连接,则直接进入CLOSED状态。

    4.SYN_RCVD:跟3对应,服务器端接受客户端的SYN请求,服务器端由LISTEN状态进入SYN_RCVD状态。同时服务器端要回应一个ACK,同时发送一个SYN给客户端;另外一种情况,客户端在发起SYN的同时接收到服务器端得SYN请求,客户端就会由SYN_SENT到SYN_RCVD状态。

    5.ESTABLISHED:服务器端和客户端在完成3次握手进入状态,说明已经可以开始传输数据了。

    以上是建立连接时服务器端和客户端产生的状态转移说明。相对来说比较简单明了,如果你对三次握手比较熟悉,建立连接时的状态转移还是很容易理解。

    下面,我们来看看连接关闭时候的状态转移说明,关闭需要进行4次双方的交互,还包括要处理一些善后工作(TIME_WAIT状态),注意,这里主动关闭的一方或被动关闭的一方不是指特指服务器端或者客户端,是相对于谁先发起关闭请求来说的:

    6.FIN_WAIT_1:主动关闭的一方,由状态5进入此状态。具体的动作是发送FIN给对方。

    7.FIN_WAIT_2:主动关闭的一方,接收到对方的FIN-ACK(即fin包的回应包),进入此状态。

    8.CLOSE_WAIT:接收到FIN以后,被动关闭的一方进入此状态。具体动作是接收到FIN,同时发送ACK。(之所以叫close_wait可以理解为被动关闭方此时正在等待上层应用发出关闭连接指令)

    9.LAST_ACK:被动关闭的一方,发起关闭请求,由状态8进入此状态。具体动作是发送FIN给对方,同时在接收到ACK时进入CLOSED状态。

    10.CLOSING:两边同时发起关闭请求时,会由FIN_WAIT_1进入此状态。具体动作是接收到FIN请求,同时响应一个ACK。

    11.TIME_WAIT:最纠结的状态来了。从状态图上可以看出,有3个状态可以转化成它,我们一一来分析:

    • a.由FIN_WAIT_2进入此状态:在双方不同时发起FIN的情况下,主动关闭的一方在完成自身发起的关闭请求后,接收到被动关闭一方的FIN后进入的状态。

    • b.由CLOSING状态进入:双方同时发起关闭,都做了发起FIN的请求,同时接收到了FIN并做了ACK的情况下,由CLOSING状态进入。

    • c.由FIN_WAIT_1状态进入:同时接受到FIN(对方发起),ACK(本身发起的FIN回应),与b的区别在于本身发起的FIN回应的ACK先于对方的FIN请求到达,而b是FIN先到达。这种情况概率最小。


    为什么需要 TIME_WAIT 状态

    假设最终的 ACK 丢失 , server 将重发 FIN , client 必须维护 TCP 状态信息以便可以重发最终的 ACK ,否则会发送RST ,结果 server 认为发生错误。 TCP 实现必须可靠地终止连接的两个方向 ( 全双工关闭 ) , client 必须进 TIME_WAIT状态,因为 client 可能面临重发最终 ACK 的情形。先调用 close() 的一方会进入 TIME_WAIT 状态


    为什么 TIME_WAIT 状态需要保持 2MSL 的时间

    如果 TIME_WAIT 状态保持时间不足够长 ( 比如小于 2MSL) ,第一个连接就正常终止了。 第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。 TCP 实现必须防止某个连接的重复报文在连接终止后出现,所以让 TIME_WAIT 状态保持时间足够长 (2MSL) ,连接相应方向上的 TCP 报文要么完全响应完毕,要么被丢弃。建立第二个连接的时候,不会混淆。


    根据《TCP/IP详解》中的TCP的建立和终止中有关"TCP的终止"的讲解

    TCP的终止通过双方的四次握手实现。发起终止的一方执行主动关闭,响应的另一方执行被动关闭。

    发起方更改状态为FIN_WAIT_1,关闭应用程序进程,发出一个TCP的FIN段;

    接收方收到FIN段,返回一个带确认序号的ACK,同时向自己对应的进程发送一个文件结束符EOF,同时更改状态为CLOSE_WAIT,发起方接到 ACK后状态更改为FIN_WAIT_2;

    接收方关闭应用程序进程,更改状态为LAST_ACK,并向对方发出一个TCP的FIN段;

    发起方接到FIN后状态更改为TIME_WAIT,并发出这个FIN的ACK确认。ACK发送成功后(2MSL内)双方TCP状态变为CLOSED。

    我们不难看出上面的显示的结果的意思。根据TCP协议,主动发起关闭的一方,会进入TIME_WAIT状态(TCP实现必须可靠地终止连接的两个方向(全双工关闭)),持续2*MSL (Max Segment Lifetime),缺省为240秒。


    TIME_WAIT状态的作用

    主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。


    TIME_WAIT状态存在的理由

    1)可靠地实现TCP全双工连接的终止

    在进行关闭连接四路握手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允 许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出connection reset的SocketException)。因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭 的客户端必须维持状态信息进入TIME_WAIT状态。

    2)允许老的重复分节在网络中消逝

    TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个 原来的迷途分节就称为lost duplicate。在关闭一个TCP连接后,马上又重新建立起一个相同的IP地址和端口之间的TCP连接,后一个连接被称为前一个连接的化身 (incarnation),那么有可能出现这种情况,前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。为了避免这个情 况,TCP不允许处于TIME_WAIT状态的连接启动一个新的化身,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时 候,来自连接先前化身的重复分组已经在网络中消逝。

    本博客文章除特别声明,全部都是原创!

    尊重原创,转载请注明: 转载自过往记忆(http://www.iteblog.com/)

    本文链接地址: 《TCP/IP状态图的TIME_WAIT作用》(http://www.iteblog.com/archives/169)

    参考:http://www.cricode.com/3568.html

    展开全文
  • TCP协议连接建立与连接断开过程(含断开时的TCP状态图) 博客分类:  技术类 网络协议应用服务器Linux网络应用数据结构  TCP协议连接建立时3次握手的过程。 简述TCP协议连接建立时3次握手...
     
    
    TCP协议连接建立时3次握手的过程。

    简述TCP协议连接建立时3次握手的过程。

    根据TCP头部,说明下列3个包在连接建立过程中的次序.

    0020        00 50 83 aa 46 49 3e dd 33 96 37 a3 a0 12  ...P..FI>.3.7...

    0030   16 a0 c4 c0 00 00 02 04 05 b4 04 02 08 0a d7 9b  ................

    0040   62 b7 00 56 4a 2a 01 03 03 02                    b..VJ*....   1

    0020        83 aa 00 50 33 96 37 a2 00 00 00 00 a0 02  .....P3.7.......

    0030   16 d0 84 1d 00 00 02 04 05 b4 04 02 08 0a 00 56  ...............V

    0040   4a 2a 00 00 00 00 01 03 03 00                    J*........    2

    0020        83 aa 00 50 33 96 37 a3 46 49 3e de 80 10  .....P3.7.FI>...

    0030   16 d0 f3 4b 00 00 01 01 08 0a 00 56 4a 36 d7 9b  ...K.......VJ6..

    0040   62 b7                                            b.    3

     

    解:

    TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

     

    1)是第二次握手,flags位上为12,二进制是0001 0010,即表示有syn和ack.

    2)是第一次握手,flags位上为02,二进制是0000 0010,即表示有syn没有ack。

    3)是第三次握手,flags位上为10,二进制是0001 0000,即表示有ack没有syn。

     

    该连接访问的是80端口,是为HTTP(HyperText Transport Protocol,超文本传输协议)开放的,

    第一次握手:建立连接时,客户端发送syn(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 

    第二次握手:服务器收到syn包,必须确认客户的SYNack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
     

    第三次握手:客户端收到服务器的SYNACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
     

    完成三次握手,客户端与服务器开始传送数据。

    tcp-断开连接:

     

    主要部分,四次握手:

    断开连接其实从我的角度看不区分客户端和服务器端,任何一方都可以调用close(or closesocket)之类
    的函数开始主动终止一个连接。这里先暂时说正常情况。当调用close函数断开一个连接时,主动断开的
    一方发送FIN(finish报文给对方。有了之前的经验,我想你应该明白我说的FIN报文时什么东西。也就是
    一个设置了FIN标志位的报文段。FIN报文也可能附加用户数据,如果这一方还有数据要发送时,将数据附
    加到这个FIN报文时完全正常的。之后你会看到,这种附加报文还会有很多,例如ACK报文。我们所要把握
    的原则是,TCP肯定会力所能及地达到最大效率,所以你能够想到的优化方法,我想TCP都会想到。

    当被动关闭的一方收到FIN报文时,它会发送ACK确认报文(对于ACK这个东西你应该很熟悉了)。这里有个
    东西要注意,因为TCP是双工的,也就是说,你可以想象一对TCP连接上有两条数据通路。当发送FIN报文
    时,意思是说,发送FIN的一端就不能发送数据,也就是关闭了其中一条数据通路。被动关闭的一端发送
    了ACK后,应用层通常就会检测到这个连接即将断开,然后被动断开的应用层调用close关闭连接。

    我可以告诉你,一旦当你调用close(or closesocket),这一端就会发送FIN报文。也就是说,现在被动
    关闭的一端也发送FIN给主动关闭端。有时候,被动关闭端会将ACK和FIN两个报文合在一起发送。主动
    关闭端收到FIN后也发送ACK,然后整个连接关闭(事实上还没完全关闭,只是关闭需要交换的报文发送
    完毕),四次握手完成。如你所见,因为被动关闭端可能会将ACK和FIN合到一起发送,所以这也算不上
    严格的四次握手---四个报文段。

    在前面的文章中,我一直没提TCP的状态转换。在这里我还是在犹豫是不是该将那张四处通用的图拿出来,
    不过,这里我只给出断开连接时的状态转换图,摘自<The TCP/IP Guide>:

    tcpclose

    给出一个正常关闭时的windump信息:

    14:00:38.819856 IP cd-zhangmin.1748 > 220.181.37.55.80: F 1:1(0) ack 1 win 65535
    14:00:38.863989 IP 220.181.37.55.80 > cd-zhangmin.1748: F 1:1(0) ack 2 win 2920
    14:00:38.864412 IP cd-zhangmin.1748 > 220.181.37.55.80: . ack 2 win 65535

     

    补充细节:

    关于以上的四次握手,我补充下细节:
    1. 默认情况下(不改变socket选项),当你调用close( or closesocket,以下说close不再重复)时,如果
    发送缓冲中还有数据,TCP会继续把数据发送完。


    2. 发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。


    3. 应用层如何知道对端关闭?通常,在最简单的阻塞模型中,当你调用recv时,如果返回0,则表示对端
    关闭。在这个时候通常的做法就是也调用close,那么TCP层就发送FIN,继续完成四次握手。如果你不调用
    close,那么对端就会处于FIN_WAIT_2状态,而本端则会处于CLOSE_WAIT状态。这个可以写代码试试。


    4. 在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关
    闭,你可以写代码试试。

     

     

     

    特别的TIME_WAIT状态:

    从以上TCP连接关闭的状态转换图可以看出,主动关闭的一方在发送完对对方FIN报文的确认(ACK)报文后,
    会进入TIME_WAIT状态。TIME_WAIT状态也称为2MSL状态。

    什么是2MSL?MSL即Maximum Segment Lifetime,也就是报文最大生存时间,引用<TCP/IP详解>中的话:“
    它(MSL)是任何报文段被丢弃前在网络内的最长时间。”那么,2MSL也就是这个时间的2倍。其实我觉得没
    必要把这个MSL的确切含义搞明白,你所需要明白的是,当TCP连接完成四个报文段的交换时,主动关闭的
    一方将继续等待一定时间(2-4分钟),即使两端的应用程序结束。你可以写代码试试,然后用netstat查看下。

    为什么需要2MSL?根据<TCP/IP详解>和<The TCP/IP Guide>中的说法,有两个原因:
    其一,保证发送的ACK会成功发送到对方,如何保证?我觉得可能是通过超时计时器发送。这个就很难用
    代码演示了。
    其二,报文可能会被混淆,意思是说,其他时候的连接可能会被当作本次的连接。直接引用<The TCP/IP Guide>
    的说法:The second is to provide a “buffering period” between the end of this connection 
    and any subsequent ones. If not for this period, it is possible that packets from different 
    connections could be mixed, creating confusion.

    TIME_WAIT状态所带来的影响:

    当某个连接的一端处于TIME_WAIT状态时,该连接将不能再被使用。事实上,对于我们比较有现实意义的
    是,这个端口将不能再被使用。某个端口处于TIME_WAIT状态(其实应该是这个连接)时,这意味着这个TCP
    连接并没有断开(完全断开),那么,如果你bind这个端口,就会失败。

    对于服务器而言,如果服务器突然crash掉了,那么它将无法再2MSL内重新启动,因为bind会失败。解决这
    个问题的一个方法就是设置socket的SO_REUSEADDR选项。这个选项意味着你可以重用一个地址。

    对于TIME_WAIT的插曲:

    当建立一个TCP连接时,服务器端会继续用原有端口监听,同时用这个端口与客户端通信。而客户端默认情况
    下会使用一个随机端口与服务器端的监听端口通信。有时候,为了服务器端的安全性,我们需要对客户端进行
    验证,即限定某个IP某个特定端口的客户端。客户端可以使用bind来使用特定的端口。

    对于服务器端,当设置了SO_REUSEADDR选项时,它可以在2MSL内启动并listen成功。但是对于客户端,当使
    用bind并设置SO_REUSEADDR时,如果在2MSL内启动,虽然bind会成功,但是在windows平台上connect会失败。
    而在linux上则不存在这个问题。(我的实验平台:winxp, ubuntu7.10)

    要解决windows平台的这个问题,可以设置SO_LINGER选项。SO_LINGER选项决定调用close时,TCP的行为。
    SO_LINGER涉及到linger结构体,如果设置结构体中l_onoff为非0,l_linger为0,那么调用close时TCP连接
    会立刻断开,TCP不会将发送缓冲中未发送的数据发送,而是立即发送一个RST报文给对方,这个时候TCP连
    接就不会进入TIME_WAIT状态。

    如你所见,这样做虽然解决了问题,但是并不安全。通过以上方式设置SO_LINGER状态,等同于设置SO_DONTLINGER
    状态。

    断开连接时的意外:
    这个算不上断开连接时的意外,当TCP连接发生一些物理上的意外情况时,例如网线断开,linux上的TCP实现
    会依然认为该连接有效,而windows则会在一定时间后返回错误信息。

    这似乎可以通过设置SO_KEEPALIVE选项来解决,不过不知道这个选项是否对于所有平台都有效。

    展开全文
  • TCP状态图和常见问题

    千次阅读 2009-09-27 22:09:00
    TCP共有9个网路状态,其中涉及到关闭的状态有5个。 在我们编写网络相关程序的时候,这5个状态经常出现。因为这5个状态相互关联,相互纠缠,而且状态变化触发都是由应用触发,但是又涉及操作系统和网络,所以正确的...

    TCP 共有9 个网路状态,其中涉及到关闭的状态有5 个。

           在我们编写网络相关程序的时候,这5 个状态经常出现。因为这5 个状态相互关联,相互纠缠,而且状态变化触发都是由应用触发,但是又涉及操作系统和网络,所以正确的理解TCP 在关闭时网络状态变化情况,为我们诊断网络中各种问题,快速定位故障有着非常重要的作用和意义。

           为此,我根据W.Richard Stevens 的《TCP/IP 详解》一书,将这5 个状态制成一个时序图(其实原书也有这个图,但不是很好理解),其中黑色字体来表示应用程序行为,红色字体是操作系统行为。

    TCP状态转换图

    =============================================================

    ===========================================================

          深刻理解上面两幅图对于编写基于TCP/IP的应用直观重要,尤其是在链接不正常时,非常有助于定位问题所在。下面给出一些常见问题和解答。

     

     

    netstat -na -P tcp -f inet | grep TIME_WAIT

    --------------------------------------------------------------------------

     

    不要设置 tcpb_time_wait_expire 成零,只要是一个很小的值就可以了。这里必须同

    时设置 tcpb_time_wait_expire tcpb_state ,只设置其中一个达不到效果。

     

    利用 adb TCPS_ESTABLISHED 变为 TCPS_CLOSE_WAIT ,可以使一条 TCP 连接不再工作, 但这条连接并未销毁, tcpb_t 结构也未删除。

     

    利用 adb TCPS_ESTABLISHED 变为 TCPS_CLOSED ,会导致整个操作系统崩溃。可能是下 tcpb_t 结构被删除,而上层 socket 并不了解,出现非法指针。

     

    简化一下 kill_timewait.sh

     

    --------------------------------------------------------------------------

    #! /sbin/sh

     

    ndd /dev/tcp tcp_status | nawk '{print $1 " " $2 " " $16 $17 " " $18}' | egrep 'TIME_WAIT'

     

    echo

    /usr/bin/echo 'TCPB address to terminate: /c'

    read tcpb_addr

    echo

     

    adb -kw /dev/ksyms /dev/mem << NSFOCUS_EOF

    $tcpb_addr+0x30/Z 0t6

    $tcpb_addr+0x40/W -6

    /$q

    NSFOCUS_EOF

    --------------------------------------------------------------------------

     

    还可以写一个脚本自动清除所有 TIME_WAIT 状态 TCP 连接

     

    --------------------------------------------------------------------------

    #! /sbin/sh

     

    ndd /dev/tcp tcp_status | nawk '{print $1 " " $2 " " $16 $17 " " $18}' | /

    egrep 'TIME_WAIT' | cut -d' ' -f1 | while read tcpb_addr

    do

    adb -kw /dev/ksyms /dev/mem << NSFOCUS_EOF

    $tcpb_addr+0x30/Z 0t6

    $tcpb_addr+0x40/W -6

    /$q

    NSFOCUS_EOF

    Done

     


    =========================================                                     

    Q: 我正在写一个 unix server 程序,不是 daemon ,经常需要在命令行上重启它,绝大多数时候工作正常,但是某些时候会报告 "bind: address in use" ,于是重启失 败。

    A: Andrew Gierth
    server
    程序总是应该在调用 bind() 之前设置 SO_REUSEADDR 套接字选项。至于 TIME_WAIT 状态,你无法避免,那是 TCP 协议的一部分。

    Q:
    如何避免等待 60 秒之后才能重启服务

    A: Erik Max Francis

    使用 setsockopt ,比如

    --------------------------------------------------------------------------
    int option = 1;

    if ( setsockopt ( masterSocket, SOL_SOCKET, SO_REUSEADDR, &option,
    sizeof( option ) ) < 0 )
    {
    die( "setsockopt" );
    }
    --------------------------------------------------------------------------

    Q:
    编写 TCP/SOCK_STREAM 服务程序时, SO_REUSEADDR 到底什么意思?

    A:
    这个套接字选项通知内核,如果端口忙,但 TCP 状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而 TCP 状态位于其他状态,重用端口时依旧得到一个错误信息,指明 " 地址已经使用中 " 如果你的服务程序停止后想立即重启 ,而新套接字依旧使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期 望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不 可能。

    一个套接字由相关五元组构成,协议 、本地地址、本地端口、远程地址、远程端
    口。 SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口 ,整个相关五元组 还是唯一确定的。所以,重启后的服务程序有可能收到非期望数据 。必须慎重使用 SO_REUSEADDR 选项。

    Q:
    在客户机 / 服务器编程中 (TCP/SOCK_STREAM) ,如何理解 TCP 自动机 TIME_WAIT 状态?

    A: W. Richard Stevens <1999
    年逝世,享年 49 >

    下面我来解释一下 TIME_WAIT 状态,这些在 <> 2.6 节解释很清楚了。

    MSL(
    最大分段生存期 ) 指明 TCP 报文在 Internet 上最长生存时间,每个具体的 TCP 实现 都必须选择一个确定的 MSL 值。 RFC 1122 建议是 2 分钟,但 BSD 传统实现采用了 30 秒。 TIME_WAIT 状态最大保持时间是 2 * MSL ,也就是 1-4 分钟。 IP 头部有一个 TTL ,最大值 255 。尽管 TTL 的单位不是秒 ( 根本和时间无关 ) ,我们仍需 假设, TTL 255 TCP 报文在 Internet 上生存时间不能超过 MSL

    TCP
    报文在传送过程中可能因为路由故障被迫缓冲延迟、选择非最优路径等等,结果发送方 TCP 机制开始超时重传 。前一个 TCP 报文可以称为 " 漫游 TCP 重复报文 " ,后一个 TCP 报文可以称为 " 超时重传 TCP 重复报文 " ,作为面向连接的可靠协议, TCP 实现必须正确处理这种重复报文,因为二者可能最终都到达。

    一个通常的 TCP 连接终止 可以用图描述如下:

    client server
    FIN M
    close -----------------> (
    被动关闭 )
    ACK M+1
    <-----------------
    FIN N
    <----------------- close
    ACK N+1
    ----------------->

    为什么需要 TIME_WAIT 状态?

    假设最终的 ACK 丢失 server 重发 FIN client 必须维护 TCP 状态信息以便可以重发最终的 ACK 否则会发送 RST ,结果 server 认为发生错误。 TCP 实现必须可靠地终止连接的两个方向 ( 全双工关闭 ) client 必须进 TIME_WAIT 状态,因为 client 可能面临重发最终 ACK 的情形。

    {
    scz 2001-08-31 13:28
    先调用 close() 的一方会进入 TIME_WAIT 状态
    }

    此外,考虑一种情况, TCP 实现可能面临先后两个同样的相关五元组。如果前一个连接处在 TIME_WAIT 状态,而允许另一个拥有相同相关五元组的连接出现,可能处理 TCP 报文时,两个连接互相干扰。使用 SO_REUSEADDR 选项就需要考虑这种情况。

    为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?

    如果 TIME_WAIT 状态保持时间不足够长 ( 比如小于 2MSL) ,第一个连接就正常终止了。 第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。 TCP 实现必须防止某个连接的重复报文在连接终止后出现,所以让 TIME_WAIT 状态保持时间足够长 (2MSL) ,连接相应方向上的 TCP 报文要么完全响应完毕,要么被丢弃。建立第二个连接的时候,不会混淆。

    A:
    小四

    Solaris 7 下有内核参数对应 TIME_WAIT 状态保持时间

    # ndd -get /dev/tcp tcp_time_wait_interval
    240000
    # ndd -set /dev/tcp tcp_time_wait_interval 1000

    缺省设置是 240000ms ,也就是 4 分钟。如果用 ndd 修改这个值,最小只能设置到 1000ms
    也就是 1 秒。显然内核做了限制,需要 Kernel Hacking

    # echo "tcp_param_arr/W 0t0" | adb -kw /dev/ksyms /dev/mem
    physmem 3b72
    tcp_param_arr: 0x3e8 = 0x0
    # ndd -set /dev/tcp tcp_time_wait_interval 0

    我不知道这样做有什么灾难性后果,参看 <> 的声明。

    Q: TIME_WAIT
    状态保持时间为 0 会有什么灾难性后果?在普遍的现实应用中,好象也就是服务器不稳定点,不见得有什么灾难性后果吧?

    D: rain@bbs.whnet.edu.cn

    Linux
    内核源码 /usr/src/linux/include/net/tcp.h

    #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully
    * close the socket, about 60 seconds */

    最好不要改为 0 ,改成 1 。端口分配是从上一次分配的端口号 +1 开始分配的,所以一般 不会有什么问题。端口分配算法在 tcp_ipv4.c tcp_v4_get_port 中。

     

     

    监听地址问题

    [root@localhost i386]# netstat -nlp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address        Foreign Address             State       PID/Program name   
    tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      2804/mysqld         
    tcp        0      0 222.230.14.16:80          0.0.0.0:*                   LISTEN      4433/(squid)        
    tcp        0      0 127.0.0.1:80                0.0.0.0:*                   LISTEN      4350/httpd         
    tcp        0      0 127.0.0.1:2006              0.0.0.0:*                   LISTEN      27724/php           
    tcp        0      0 0.0.0.0:25                    0.0.0.0:*                   LISTEN      26234/master        
    tcp        0      0 0.0.0.0:443                  0.0.0.0:*                   LISTEN      27724/php           
    tcp        0      0 :::22                           :::*                        LISTEN      2674/sshd           
    udp        0      0 0.0.0.0:16384              0.0.0.0:*                                  4433/(squid)        
    udp        0      0 0.0.0.0:3130               0.0.0.0:*                                   4433/(squid)      

    我说的本地地址的四种类型:
    0 0.0.0.0
    222.230.14.16
    127.0.0.1
    :::
    都是本地地址为何要有这四种类型呢?都是代表什么含义和作用呢?

     

    一般 0.0.0.0 表示 all or any address , listen 0.0.0.0 來說 , 表示 listen 主机所有 interface ip 位址 .

    至於你說的 222.230.14.16 or 127.0.0.1 那都只是表示 listen 特定 ip 位址 而已 ..

    ::: 那表示 listen 主机所有 interface ipv6 位址 .

     

     

    网络字节序问题

    低地址   。。。。。。。。高地址
    04     03     02     01    
    ------》方法 1
    01     02     03     04    
    ------》方法 2

    上面是整数 0x01020304 的两种表示方法,其中方法 1 和方法 2 的区别就是高位放到高地址还是低地址。

    方法 叫做小端格式,方法 2 叫做大端格式,网络上使用的大端格式 ,而主机格式随着不同的机器不同,为了使得不同的主机格式能够无歧义的和网络格式相互赋值,一般牵涉到网络的开发库会定义一套两种格式之间的转换函数,这样直接使用转换函数就可以完成两者之间的转换。

    例如在 windows 中有 htons ntohs htonl ntohl 等一套函数,分别用来完成 2 个字节和 4 个字节的转换。

     

    展开全文
  • TCP连接状态图解析

    千次阅读 2016-03-19 21:17:59
    TCP状态图,展示的是TCP从连接建立到连接关闭的整个生命周期, TCP的状态转换以及处理流程。TCP面向的是端口,Linux里面可以通过 netstat -a命令查看连接状态。笔者遇到Tomcat生成大量CLOSE_WAIT 状态的连接问题...
  • TCP协议状态图

    2013-04-13 08:19:28
    用VISSO画的TCP协议状态图,用于表示TCp的状态的转换.
  • tcp状态转换

    2018-03-13 11:58:15
    tcp状态图,高清,可以收藏多年。
  • tcp握手状态图 kkkkkkkkkkk kkkkk kkkk
  • TCP状态转换

    2014-04-26 19:50:11
    最全的TCP状态转换
  • TCP状态迁移

    2014-11-02 11:03:40
    绘制TCP状态迁移,可以根据TCP的连接
  • 详细的介绍了TCP状态转换以及TCP状态。并且给出了TCP状态转换
  • TCP状态转换详解 tcp协议讲解

    万次阅读 2018-09-27 15:38:28
    如下所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手)、数据传输、断开TCP连接通道(四次挥手)。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&...
  • TCP状态切换变化

    2020-07-05 14:17:14
    传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。本资源是TCP协议的状态变化,不同状态收到不同包时的状态切换。
  • TCP状态转换图文解说

    千次阅读 2020-10-28 19:30:46
    文章目录一、TCP状态转换说明状态转换二、名次解释2MSL半关闭补充:Linux命令:查看网络相关状态补充:端口复用FIN_WAIT2TIME_WAIT 一、TCP状态转换 说明 状态转换 TCP初始化时从CLOSED状态启动,通常...
  • TCP状态转换详解

    千次阅读 2018-06-08 20:02:29
    在前面,已经介绍了TCP协议的三路握手和四次挥手。如下所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手)、数据传输、断开TCP连接通道(四次挥手)。...先看TCP状态状态转换。 ...
  • TCP状态变迁 TCP状态变迁-描述各个状态之间变迁
  • 详解TCP状态转移

    千次阅读 2018-02-27 15:27:24
    根据TCP状态转移过程,可进行一步一步分析。 一般而言,TCP连接是由客户端发起,并通过三次握手建立连接(特殊情况是所谓同时打开)的。 TCP关闭过程相对复杂一些,可能是客户端执行主动关闭;也可能是服务器...
  • tcp状态迁移

    千次阅读 2013-10-04 17:36:43
    TCP正常建立和关闭的状态变化     TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做 四次握手。   建立连接   在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手...
  • TCP状态变迁

    2008-09-12 11:55:10
    TCP状态变迁.jpg 描述的非常详细
  • TCP建链拆链状态图

    2011-12-18 23:06:39
    TCP状态变迁 主要是建链拆链,同时建链拆链各种情况
  • TCP状态迁移浅析

    千次阅读 2013-09-12 09:35:05
    一.TCP简介  TCP提供一种面向连接的,可靠的字节流服务。面对连接意味着两个使用TCP的应用,在彼此交换数据之前必须先建立一个连接。TCP通过以下方式提供可靠性:  1. 应用数据被分割成TCP认为最适合发送的数据块...
  • TCP状态转换

    千次阅读 2018-09-17 21:57:55
    TCP状态转换  TCP连接的建立与终止,以及在连接的不同阶段需要发送的各种类型的报文段,实质上都是由TCP所属的状态决定的。当前的状态会在各种触发条件下改变,状态转换规则可以概括为如下所示的TCP状态转换:...
  • TCP状态变迁

    2012-01-14 19:14:07
    TCP状态变迁,用于了解TCP原理。
  • tcp状态转移

    千次阅读 2011-05-09 17:05:00

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 271,188
精华内容 108,475
关键字:

tcp状态图