RFC 793 记录

 TCP 状态变迁图:

                              +---------+ ---------/      active OPEN  
                              |  CLOSED |            /    -----------  
                              +---------+<---------/   /   create TCB  
                                |     ^              /   /  snd SYN    
                   passive OPEN |     |   CLOSE        /   /           
                   ------------ |     | ----------       /   /         
                    create TCB  |     | delete TCB         /   /       
                                V     |                      /   /     
                              +---------+            CLOSE    |    /   
                              |  LISTEN |          ---------- |     |  
                              +---------+          delete TCB |     |  
                   rcv SYN      |     |     SEND              |     |  
                  -----------   |     |    -------            |     V  
 +---------+      snd SYN,ACK  /       /   snd SYN          +---------+
 |         |<-----------------           ------------------>|         |
 |   SYN   |                    rcv SYN                     |   SYN   |
 |   RCVD  |<-----------------------------------------------|   SENT  |
 |         |                    snd ACK                     |         |
 |         |------------------           -------------------|         |
 +---------+   rcv ACK of SYN  /       /  rcv SYN,ACK       +---------+
   |           --------------   |     |   -----------                  
   |                  x         |     |     snd ACK                    
   |                            V     V                                
   |  CLOSE                   +---------+                              
   | -------                  |  ESTAB  |                              
   | snd FIN                  +---------+                              
   |                   CLOSE    |     |    rcv FIN                     
   V                  -------   |     |    -------                     
 +---------+          snd FIN  /       /   snd ACK          +---------+
 |  FIN    |<-----------------           ------------------>|  CLOSE  |
 | WAIT-1  |------------------                              |   WAIT  |
 +---------+          rcv FIN  /                            +---------+
   | rcv ACK of FIN   -------   |                            CLOSE  |  
   | --------------   snd ACK   |                           ------- |  
   V        x                   V                           snd FIN V  
 +---------+                  +---------+                   +---------+
 |FINWAIT-2|                  | CLOSING |                   | LAST-ACK|
 +---------+                  +---------+                   +---------+
   |                rcv ACK of FIN |                 rcv ACK of FIN |  
   |  rcv FIN       -------------- |    Timeout=2MSL -------------- |  
   |  -------              x       V    ------------        x       V  
    / snd ACK                 +---------+delete TCB         +---------+
     ------------------------>|TIME WAIT|------------------>| CLOSED  |
                              +---------+                   +---------+

  
  
   
    
  
  
                      
   
   
    
    
     
     TCP
    
    
    
     
    
    
     
     Connection
    
    
    
     
    
    
     
     State
    
    
   
    Diagram
                               Figure 6.
3.3 序列号

有多个未决定的具有相同本地socket的被动打开时,优先选择指定外部socket的那个请求来建立连接


序列号产生每4.55小时循环一次

RFC793规定最大分片生存时间MSL为2分钟

静止时间最好要实现.否则可能出现序列号重复出现.旧的分片被当成新的分片被接收.


3.4 建立连接
建立连接的三次握手是一个同步双方初始序列号的过程.
三次握手的基本原则是防止老的重复的连接引起混乱.为了处理这个,reset控制信息被提了出来.

接收SYN段时是处理SYN-RECEIVED状态,接收到ACK段才处理ESTABLISHED状态


1)一方主动打开,一方被动打开(典型三次握手):
      TCP A                                                TCP B
 
  1.  CLOSED                                               LISTEN
 
  2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED
 
  3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED
 
  4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED
 
  5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

2)双方同时主动打开:
     TCP A                                            TCP B
 
  1.  CLOSED                                           CLOSED
 
  2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...
 
  3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT
 
  4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED
 
  5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...
 
  6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
 
  7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> ESTABLISHED

3)rst复位从老的重复分片中恢复
      TCP A                                                TCP B
 
  1.  CLOSED                                               LISTEN
 
  2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               ...
 
  3.  (duplicate) ... <SEQ=90><CTL=SYN>               --> SYN-RECEIVED
 
  4.  SYN-SENT    <-- <SEQ=300><ACK=91><CTL=SYN,ACK>  <-- SYN-RECEIVED
 
  5.  SYN-SENT    --> <SEQ=91><CTL=RST>               --> LISTEN
 
  6.              ... <SEQ=100><CTL=SYN>               --> SYN-RECEIVED
 
  7.  SYN-SENT    <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED
 
  8.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> ESTABLISHED
 
                    Recovery from Old Duplicate SYN
发送端发送复位信息的序列号应为接收端的确认号,而不是发送端的当前的序列号.否则接收端判断接收到的序列号不是预期的序列号时,也会发送一个复位信息,并且不接受该复位信息.
比如若6在5之前到达,接收端就会发回一个复位信息.


4).半打开连接,发送端尝试建立新的连接
      TCP A                                           TCP B
 
  1.  (CRASH)                               (send 300,receive 100)
 
  2.  CLOSED                                           ESTABLISHED
 
  3.  SYN-SENT --> <SEQ=400><CTL=SYN>              --> (??)
 
  4.  (!!)     <-- <SEQ=300><ACK=100><CTL=ACK>     <-- ESTABLISHED
 
  5.  SYN-SENT --> <SEQ=100><CTL=RST>              --> (Abort!!)
 
  6.  SYN-SENT                                         CLOSED
 
  7.  SYN-SENT --> <SEQ=400><CTL=SYN>              -->

接收端接收到不同步的信息,会继续发送它预期接收的确认信息
发送端接收到不同步的信息,会发送RST复立信息

5).半打开连接,接收端尝试继续通信
       TCP A                                              TCP B
 
  1.  (CRASH)                                   (send 300,receive 100)
 
  2.  (??)    <-- <SEQ=300><ACK=100><DATA=10><CTL=ACK> <-- ESTABLISHED
 
  3.          --> <SEQ=100><CTL=RST>                   --> (ABORT!!)
 
           Active Side Causes Half-Open Connection Discovery
6).我们发现TCP A和B都处于被动等待SYN连接。一个老的重复分片到达TCP B(线2),触发了B的动作。一个SYN-ACK被返回(线3),并且导致了TCP A产生了一个RST(线3的ACK是不能被接受的),TCP B接受了reset,且返回到被动监听状态。

      TCP A                                         TCP B
 
  1.  LISTEN                                        LISTEN
 
  2.       ... <SEQ=Z><CTL=SYN>                -->  SYN-RECEIVED
 
  3.  (??) <-- <SEQ=X><ACK=Z+1><CTL=SYN,ACK>   <--  SYN-RECEIVED
 
  4.       --> <SEQ=Z+1><CTL=RST>              -->  (return to LISTEN!)
 
  5.  LISTEN                                        LISTEN
 
       Old Duplicate SYN Initiates a Reset on two Passive Sockets
Rest产生

作为一条基本规则,reset(RST)在一个分片到达且明显不是当前连接的分片的任何时候必须被发送。如果还不清楚,reset不能被发送。

有三组状态:

1.       如果连接不存在(关闭),那么reset被发送来响应任何到来分片(另外一个reset除外)。特别的,属于一个不存在的连接的SYN被这个方式拒绝。
如果到来分片有ACK字段,reset从该分片的ACK字段提取系列号,否则reset系列号取0,ACK字段设置成系列号和到来分片的分片长度的和。连接保留在关闭(CLOSED)状态。

2.       如果连接处于非同步状态(LISTEN,SYN-SENT,SYN_RECEIVED),到来分片对没有发送的东西进行确认(分片携带了不被接受的ACK),或者一个到来分片同连接要求的安全级别或者分隔没有严格匹配,reset被发送。
如果我们的SYN还没有被确认且到来分片的优先级别高于要求的优先级别,则双方都提高本地优先级别(如果用户和系统允许的话)或者发送一个reset;或者如果到来分片的优先级别低于要求的优先级别,则继续,就像优先级别严格匹配一样。(如果远端TCP不能提高优先级别来匹配我们的优先级别,在下一个它发送的分片中会被检测到,且连接将会被终止)。如果我们的SYN已经被确认(可能是在这个到来的分片中),到来分片的优先级别必须同本地优先级别严格匹配,如果没有匹配,一个reset必须被发送。
如果到来分片有一个ACK字段,reset从分片的ACK字段中提取系列号。否则,reset的系列号为0,ACK字段设置成到来分片系列号和分片长度的和。连接维持同一状态。

3.       如果连接处于同步状态(ESTABLISHED,FIN-WAIT-1,FIN-WAIT-2,CLOSE-WAIT,CLOSING,LAST-ACK,TIME-WAIT),任何不被接受的分片(在系列号窗口之外或者不被接受的确认号码)必须仅发出一个包含当前发送队列号码和指示下一个期望被收到的系列号的确认的确认分片,且连接维持在相同的状态。
如果到来分片同连接要求的安全级别、分隔不一样,reset被发送,连接进入到CLOSED状态。Reset从到来分片的ACK字段提取系列号。

Reset处理

在除了SYN-SENT之外的所有状态中,所有的reset(RST)分片通过检查他们的SEQ字段被验证有效。如果一个reset的系列号在窗口内,则它是有效的。在SYN-SENT状态中(一个reset作为一个初始SYN的响应被收到),如果ACK字段确认了SYN,RST是可以接受的。

RST的接收者首先验证它,然后改变状态,如果接收者处于LISTEN状态,它可以忽略RST。如果接收者处于SYN-RECEIVED状态,且之前处于LISTEN状态,则接收者返回到LISTEN状态,否则接收者终止连接然后进入CLOSED状态。如果接收者处于其它的状态,它终止连接,告知用户,进入CLOSED状态。


3.5.关闭连接
3.5.1 本地用户发起关闭
    FIN分片被构造并放入外发分片队列中,TCP进入FIN_WAIT_1等待状态,不再接受用户的任何信息.另一端的TCP在接收到FIN后,发回一个确认TCP进入FIN_WAIT_2.用户关闭后远端TCP发送自己的FIN.本端TCP发回一个确认,进入TIME_WAIT状态.
  注意:TCP收到fin后返回一个ack确认,但不会自己发送fin,除非用户采取关闭操作.

3.5.2 TCP从网络上接受到一个FIN
  TCP通知用户并且发送一FIN到另一端,以下
3.5.3 双方同时关闭


3.6 优先级和安全
    在TCP中使用的优先级和安全参数就是那些在Internet协议(IP)中定义的优先级和安全参数安.
    一个有着不匹配的安全/间隔值或者较低优先级值的连接尝试必须通过发送一个reset被拒绝。由于优先级太低拒绝一个连接只发生在SYN的确认收到之后。
   注意,仅操作于优先级的缺省值之上的TCP模块仍会检查到来分片的优先级,且可能提高他们用于连接的优先级。

安全参数可以被用于一个非安全环境(值指示了未分类的数据),因此在非安全环境中的主机也必须准备接收安全参数,即使他们不需要发送这些参数。
 
3.7 数据通信
    一旦TCP处于ESTABLISHED状态,所有的分片都必须携带ACK信息.以更新snd.una,snd.nxt,rcv.nxt

*超时重传
RTT:分片发送至接收到确认所需的时间,往返旅行时间.
平滑往返时间SRTT = (a*SRTT) +((1-a)*RTT)

重传超时
RTO=min(ubound,max(lbound,b*srtt)))
ubound:the upper bound of timeout
lbound:the lower bound of timeout

*紧急信息通信

*管理窗口
指定大的窗口鼓励传输,但会产生过多的重传,增加网络负担.小的窗口则限制了数据的传输,导致了传输分片间的延迟.

鲁棒性原则规定TCP不应该自己收缩窗口,但对另一端的收缩有所准备.

发送TCP必须准备从用户接收数据并且至少发送一个字节的数据,即使窗口大小为0.发送TCP应该经常重传,即使窗口为0.重传时间推荐为2分钟.这可保证当窗口变大时,另一端能够进行通告.

窗口为0时,接收端要接收到新的分片时,虽然不接受这个分片,但还要发送一个包含它预期接收的序列号的确认信息及当前窗口大小0.

发送端包装数据分片以适合当前窗口大小,可能在重传队列中重新包装(虽然不是必需的,但可能很有用).

单向数据传输时确认信息的序列号都一致,当它们的确认号也一致时,如果它们没有按次序到达,就可能造成通告的窗口大小不正确,把老的窗口大小当成新的.可以使确认号大小

窗口管理建议

分配一个很小的窗口导致数据需要用很多小的分片传输,这时使用尽量少的大分片可以获取更优的性能

接收者尽量避免更新窗口,直到额外分配至少达到了连接的最大可能分配的百分X(这里X可能从20到40)

发送者尽量避免等到窗口足够大才发送小分片。如果用户用信号通知了一个push功能,则数据必须被发送,即使它是个小分片。

注意确认不能被延迟,否则会导致不必要的重传。一个策略是当一个小分片到来的时候立即发送一个确认(没有更新窗口信息),然后发送另外一个带有新的窗口信息的确认,当窗口更大的时候。

查到一个零窗口,发送可能会开始将传送数据分成越来越小的分片。如果一个包含单个数据八位字节的被发送且检查到0窗口的分片被接受,它就假定当前一个八位字节的窗口是可用的。如果发送TCP仅简单地发送任何窗口不为0的时候它能发送的数据,传输数据将会分成可以代替的大的和小的分片。随着时间的推移,在接收端让窗口分片可用的临时的停顿将导致大的分片被分成小的和不那么大的分片。过一会,数据传输会以大部分小分片进行。

这里建议TCP实现需要主动尝试连接小窗口分片成为大窗口,因为管理窗口的机制在很多简单的实现中倾向于很多小的窗口。

3.8 接口
3.8.1 用户/TCP接口
TCP的用户接口因系统而异,以下是几个所有TCP实现必需具备的功能接口.
要提供进程间通信的接口,TCP不仅要接受命令,还要返回信息给他服务的进程。后一部分包括:

(a)       一个连接的的概要信息(比如,中断,远端关闭,未指定外部端口的绑定)

(b)       回复特定的用户命令指示成功或者各种类型的失败

*OPEN (local port, foreign socket, active/passive
[, timeout] [, precedence] [, security/compartment] [, options])
-> local connection name

active:主动打开,立即进行同步,建立连接
passive:被动打开,进入listen状态

timeout:默认5min

*SEND (local connection name, buffer address, byte
count, PUSH flag, URGENT flag [,timeout])


*RECEIVE (local connection name, buffer address, byte
count) -> byte count, urgent flag, push flag

*CLOSE (local connection name)

分片到达

   1)如果处于CLOSED状态(如TCB不存在),则

       所有到来分片的数据被丢弃。包含RST的到来分片被丢弃。不包含RST的到来分片将导致RST作为响应被发送。确认和系列号字段值被选择用来使reset系列号可被发送分片的TCP接受。

       如果ACK位关闭,系列号0被使用

          <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

       如果ACK位打开

          <SEQ=SEG.ACK><CTL=RST>

   2)如果处于LISTEN状态,则

          第一步,检查下RST
   一个到来的RST必须被忽略,返回

          第二步,检查下ACK

          任何在连接仍然处于LISTEN状态下到来的确认是错误的。一个可以接受的reset分片必须为任何一个到来的ACK产生分片形成。RST格式如下:

           <SEQ=SEG.ACK><CTL=RST>

          返回

          第三步,检查SYN

          如果设置了SYN位,检查安全性。如果到来分片的安全性(security)/分隔(compartment)没有同TCB的安全性和分隔完全匹配,则发送一个reset并返回。

             <SEQ=SEG.ACK><CTL=RST>

          如果SEG.PRC大于TCB.PRC,则如果用户允许,系统设定TCB.PRC=SEG.PRC,

          如果不允许,则发送一个reset,返回。

           <SEQ=SEG.ACK><CTL=RST>

          如果SEG.PRC小于TCB.PRC则继续。

          设定RCV.NXT为SEG.SEQ+1,IRS设置成SEG.SEQ,其它的控制或者文本被放到队列中以后处理。ISS必须被选择,一个如下形式的SYN分片被发送:

<SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>

SND.NXT被设置成ISS+1,SND.UNA设置成ISS。连接状态必须被改成SYN-RECEIVED.注意任何其它的到来控制或者数据(同SYN结合)将在SYN-RECEIVED状态被处理,但是不用重复处理SYN和ACK。如果listen没有被完全指定(如,外部socket没有完全指定),则未指定字段现在必须被填充。

  第四步,其它文本或者控制

  任何其它控制或者文本产生分片(不包括SYN)都有ACK,则会被一个ACK处理丢掉。一个到来的RST分片不能是合法的,因为它不可能是为了响应任何这个连接的化身发送的。所以你不太可能收到一个RST分片,但如果收到了,丢弃分片,返回。

      3)如果处于SYN-SENT状态,则

第一,   检查ACK位
如果设置了ACK位
如果SEG.ACK=<ISS,或者SEG.ACK>SND.NXT,发送一个reset(除非设置了RST位,如果是这样的话,丢弃分片,返回)
   <SEQ=SEG.ACK><CTL=RST>
并且丢弃那个分片,返回。
如果SND.UNA=<SEG.ACK=<SND.NXT则ACK可以被接受

第二,   检查RST位
如果设置了RST位
如果ACK是可以接受的,则发信号通知用户”error:connection reset”,丢弃分片,进入CLOSED状态,删除TCB,返回。否则(没有ACK)丢弃分片返回。

第三,   检查安全性和优先级
如果分片的安全性/分隔同TCB的安全性/分隔没有完全匹配,发送一个reset
如果有一个ACK
  <SEQ=SEG.ACK><CTL=RST>
否则
  <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
如果有一个ACK
分片的优先级必须同TCB的优先级匹配,如果不匹配,发送一个reset
 <SEQ=SEG.ACK><CTL=RST>
如果没有ACK
分片的优先级高于TCB的优先级,则如果用户允许,系统就提高TCB的优先级到分片的优先级,如果不允许提高优先级,就发送一个reset
 <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
如果分片的优先级小于TCB的优先级则继续
如果发送了reset,丢弃分片,返回

第四,   检查SYN位
这一步只有当ACK是ok的时候才需要,或者当没有ACK,且分片不包含一个RST。
如果SYN位打开,且安全性/分隔和优先级可以被接受,则设置RCV.NXT为SEG.SEQ+1,设置IRS为SEG.SEQ。SND.UNA被提高到等于SEG.ACK(如果有一个ACK),且被确认过的在重传队列的任何分片必须被移走。
如果SND.UNA>ISS(我们的SYN已经被确认),改变连接状态到ESTABLISHED,组装一个ACK分片
   <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK)
然后发送它。在队列中等待重传的数据或者控制可以被包括在里面。如果分片中有其它控制或者文本,则在下面的第六步被处理(在第六步中会检查URG位),否则返回
否则进入SYN-RECEIVED,组装一个SYN,ACK分片
  <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
然后发送它。如果分片中有其它的控制或者文本,放到队列中,等到ESTABLISHED状态后进行处理,返回。

第五,   如果SYN和RST位都没有被设置,则丢弃分片,返回

4)否则,

第一步,检查系列号

  SYN-RECEIVED

  ESTABLISHED

  FIN-WAIT-1

  FIN-WAIT-2

  CLOSE-WAIT

  CLOSING

  LAST-ACK

  TIME-WAIT状态

    分片按系列号顺序被处理。对到来分片进行初始测试以丢弃老的复制分片,但进

    一步的处理以SEG.SEQ顺序进行。如果分片的内容跨越了老的分片和新的分片的

边界,则只有新的部分必须被处理。

对到来分片,有4种可接受性测试:

分片接收测试

长度         窗口   

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

0            0         SEG.SEQ = RCV.NXT

0            >0        RCV.NXT=<SEG.SEQ <RCV.NXT+RCV.WND

>0           0         不能接受

>0           >0       RCV.NXT=<SEG.SEQ<RCV.NXT+RCV.WND

                      或者

RCV.NXT=<SEG.SEQ+SEG.LEN-1<RCV.NXT+RCV.WND

如果RCV.WND是0,则不能接受分片,但是合法的ACKs,URGs和RSTs例外。

如果到来分片是不被接受的,必须发送一个确认进行响应(除非设置了RST位,如果这样的话,丢弃分片并返回):

        <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

发送确认以后,丢弃不能被接受的分片并返回。

接下来的例子假定分片是一个理想化的分片,它开始于RCV.NXT,没有超过窗口。可以通过去掉任何位于窗口之外的部分(包括SYN和FIN)对真正的分片进行剪裁以满足这个假设,且仅当分片开始于RCV.NXT时做进一步的处理。开始于高一些的系列号的分片留到以后进行处理。

第二步:检查RST位

     SYN-RECEIVED状态

       如果设定了RST位

         如果连接是由一个被动的OPEN触发(比如,从LISTEN状态变更过来),则将该连接返回到LISTEN状态并返回。不需要通知用户。如果连接是通过一个主动的OPEN触发(比如,从SYN-SENT状态转化过来),则连接被拒绝,告知用户“connection refused”.在上面两种情况中的任何一种,所有在重传队列的分片必须被从队列中移走。在主动OPEN的情况中,进入CLOSED状态,删除TCB,返回。

     ESTABLISHED

     FIN-WAIT-1

     FIN-WAIT-2

     CLOSE-WAIT

        如果设置了RST位,则任何显著的RECEIVEs和SEND都会收到“reset”响应。所有分片队列都会被清空。用户也会接收一个未被恳求的“connection reset”信号。进入CLOSED状态,删除TCB,返回。

     CLOSING状态

     LAST-ACK状态

TIME-WAIT状态

        如果设置了RST,则进入CLOSED状态,删除TCB,返回

第三步:检查安全性和优先级

     SYN-RECEIVED

         如果分片的安全性/分隔和优先级同TCB的安全性/分隔,优先级没有完全匹配,

         发送一个reset,返回

     ESTABLISHED状态

        如果分片的安全性/分隔和优先级同TCB的安全性/分隔,优先级没有完全匹配,发

送一个reset,任何显著的RECEIVEs和SEND将接收到“reset”响应。所有的分片队列必须被清空。用户也会接收到一个未被期待的“connection reset”信号。进入CLOSED状态,删除TCB,返回。

     注意这个检查是在系列号检查之后,以防一个老的连接的分片有不同的安全性或者优

先级,导致当前连接被终止掉。

第四步:检查SYN位

          SYN-RECEIVED

        ESTABLISHED

        FIN-WAIT STATE-1

        FIN-WAIT STATE-2

        CLOSE-WAIT STATE

        CLOSING STATE

        LAST-ACK STATE

        TIME-WAIT STATE

          如果SYN在窗口内,它是一个错误,发送一个reset,任何显著的RECEIVEs和

SEND将收到“reset”响应,所有的分片队列将被清除,用户也将收到一个未被

恳求的“connection reset”信号,进入CLOSED状态,删除TCB,返回。

如果SYN不在窗口内,不会到这个步骤且在第一个步骤一个ack将被发送(系

列号检查)。

第五步,检查ACK字段

如果ACK位没有打开,丢弃分片,返回

如果ACK位打开了

  SYN-RECEIVED状态

     如果SND.UNA=<SEG.ACK=<SND.NXT,则进入ESTABLISHED状态,继续处理。

       如果分片确认是不被接受的,组装一个reset分片

         <SEQ=SEG.ACK><CTL=RST>

      并发送它

   ESTABLISHED状态

     如果SND.UNA<SEG.ACK=<SND.NXT,设置SND.UNA=SEG.ACK.任何因此被确认的重传队列中的分片被移走。用户将接收到已经发送且完全被确认的缓冲的积极的确认(如,SEND缓冲将以“OK”响应返回)。如果ACK是一个重复分片(SEG.ACK<SND.UNA),它将被忽略。如果ACK确认了没有被发送的分片(SEG.ACK>SND.NXT)则发送一个ACK,丢弃分片,返回。

    如果SND.UNA<SEG.ACK=<SND.NXT,则发送窗口将被更新。如果(SND.WL1<SEG.SEQ 或者(SND.WL1=SEG.SEQ且SND.WL2=<SEG.ACK)),设置SND.WND=SEG.WND,设置SND.WL1=SEG.SEQ,并设置SND.WL2=SEG.ACK。

    注意SND.WND是从SND.UNA的一个偏移,SND.WL1记录了用来更新SND.WND的最后一个分片的系列号。这里的检查避免了使用老分片来更新窗口。

      FIN-WAIT-1 状态

         除了ESTABLISHED状态要求的处理,如果我们的FIN现在被确认则进入FIN-WAIT-2状态,并在那个状态中继续处理

      FIN-WAIT-2状态

        除了ESTABLISHED状态的处理,如果重传队列是空的,用户的CLOSE可以被确认(“OK”),但并不删除TCB

     CLOSE-WAIT状态

         同ESTBLISHED状态的处理相同

     CLOSING状态

         除了ESTABLISHED状态的处理,如果ACK确认了我们的FIN,则进入TIME-WAIT状态,否则忽略分片

      LAST-ACK状态

         在这个状态唯一要做的事情是我们的FIN的确认。如果我们的FIN现在被确认了,就删除TCB,进入CLOSED状态,返回

      TIME-WAIT状态

         这个状态能够到来的分片是远端FIN的重传。确认它,并重新启动2 MSL的超时。

  第六步,检查URG位

      ESTABLISHED STATE    

      FIN-WAIT-1 STATE

      FIN-WAIT-2 STATE

        如果设置了URG位,将RCV.UP设置成max(RCV.UP,SEG.UP),如果紧急指针在消耗掉的数据之前,告知用户远端有紧急数据。如果对于这个连续系列的紧急数据用户已经被告知(或者仍然处理“紧急模式”) ,不用再通知用户。

      CLOSE-WAIT STATE

      CLOSING STATE

      LAST-ACK STATE

      TIME-WAIT

         这不应该发生,因为已经收到了远端的FIN。忽略URG。

  第七步,处理分片文本

       ESTABLISHED STATE

       FIN-WAIT-1 STATE

       FIN-WAIT-2 STATE

          一旦处于ESTABLISHED状态,传送分片文本到用户接收缓冲就成为可能。分片的文本可以等到缓冲满或者分片为空的时候移到缓冲。如果分片为空并携带了一个PUSH标志,则当缓冲返回的时候告知用户接收到PUSH。

        当TCP负责投递数据给用户的时候,它必须对数据的收到进行确认。

        一旦TCP接管了数据,他提升RCV.NXT到接收的数据,并调整RCV.WND为适合于当前缓冲可能性的值,RCV.NXT和RCV.WND的总值不能被减少。

        请注意3.7节的窗口管理建议

        发送一个如下格式的确认:

          <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

        这个确认必须同一个分片在一块,该分片如果可能必须不延迟被传送。

    CLOSE-WAIT STATE

    CLOSING STATE

    LAST-ACK STATE

    TIME-WAIT STATE

       这不会发生,因为已经从远端收到了一个FIN。忽略分片文本。

第八步,检查FIN位

     如果处于CLOSED,LISTEN或者SYN-SENT状态,不要处理FIN,因为SEG.SEQ

不是合法的;丢弃分片,返回

如果设置了FIN位,告知用户“connection closing”,返回给任何悬而未决的RECEIVEs

同一条信息,提高RCV.NXT到FIN,发送一个FIN的确认。注意,FIN暗示了任何

未投递给用户的分片文本的PUSH操作。

   SYN-RECEIVED 状态

   ESTABLISHED 状态

         进入CLOSE-WAIT 状态

   FIN-WAIT-1 状态

      如果我们的FIN已经被确认(可能就在这个分片里面做了确认),则进入

TIME-WAIT,启动time-wait定时器,关闭其它定时器;否则进入CLOSING状

         FIN-WAIT-2 状态

           进入TIME-WAIT状态,启动time-wait定时器,关闭其它定时器

         CLOSE-WAIT 状态

           维持在CLOSE-WAIT状态

         CLOSING 状态

           维持在CLOSING状态

         LAST-ACK状态

           维持在LAST-ACK状态

         TIME-WAIT状态

            维持在TIME-WAIT状态,重新启动一个2 MSL time-wait超时。

      然后返回。

用户超时(USER TIMEOUT)

任何状态,如果用户超时已经到达,清空队列,告知用户“error:connection aborted due

to user timeout“, 对于任何显著的调用,也返回该消息,删除TCB,进入CLOSED

状态并返回

重传超时(RETRANSMISSION TIMEOUT)

   任何状态,如果重传队列中的一个分片重传超时到达,将分片再一次放到重传队列的前

面,重新初始化重传定时器,并返回

TIME-WAIT超时

   如果一个连接的time-wait到达,删除TCB,进入CLOSED状态并返回。

猜你喜欢

转载自blog.csdn.net/l1423/article/details/1731784
rfc