rfc793中文翻译四(dlmu2001)

3.5     关闭一个连接

CLOSE是表示“我已经没有数据要发送”的操作。关闭一个全双工的连接的概念属于含糊的解释,当然,既然它不清楚如何对待连接的接收端。我们选择以一个单工方式处理CLOSE。关闭连接的用户可以继续接收直到他被告知另一端也关闭了。这样,一个程序可以在CLOSE之后发起几个SENDs,然后继续接收直到由于另一端关闭RECEIVE失败。我们假定TCP会通知用户另一端已经关闭,即使没有明显的RECEIVE,这样用户可以优雅地关闭他自己这端的连接。TCP将可靠地投递所有的在连接关闭前发送的缓冲,因此一个希望没有返回数据的用户只要等待监听连接被成功关闭一直到他的所有数据被目标TCP接收。用户必须保持读取他们关闭发送的连接直到TCP说明再没有数据。

最基本的三种情况:

1)      用户通过告知TCP关闭连接发起

2)      远端TCP通过发送FIN控制信号发起

3)      双方用户同时关闭

第一种情况:本地用户发起关闭

在这种情况中,FIN分片可以被构建并放在外发分片队列中。从用户发起的SENDs不再被TCP接受,TCP进入了FIN-WAIT-1状态。RECEIVE在这个状态是允许了。所有之前发送的分片包括FIN分片都会被重传直到被确认。当其它TCP确认了FIN分片,且发送了它自己的FIN分片,第一个TCP可以确认这个FIN。注意一个接受到一个FINTCP将确认但不发送它自己的FIN,直到用户也关闭了连接。

第二种情况:TCP从网络上接受到一个FIN

如果一个未被恳求的FIN从网络上到达,接收TCP可以确认它,然后告知用户连接正在关闭。用户以CLOSE响应,在这个过程中TCP在发送完任何剩下的数据后可以发送一个FIN给另一个TCP。然后TCP等待它自己的FIN被确认后关闭连接。如果ACK没有到来,则在用户超时后连接被终止,用户也会被告知。

第三种情况:双方用户同时关闭

连接两端FIN同时被用户关闭导致FIN分片被交换。当FIN之前的所有分片被处理和确认,每个TCP可以确认它收到的FIN。双方在接收到这些ACK后将删除连接。


  
  
   
    
  
  

 

      TCP A                                                TCP B

  
  
   
    
  
  
  1.  ESTABLISHED                                         ESTABLISHED

  
  
   
    
  
  
  2.  (Close)
      FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  --> CLOSE-WAIT

  
  
   
    
  
  
  3.  FIN-WAIT-2  <-- <SEQ=300><ACK=101><CTL=ACK>      <-- CLOSE-WAIT

  
  
   
    
  
  
  4.                                                       (Close)
      TIME-WAIT   <-- <SEQ=300><ACK=101><CTL=FIN,ACK>  <-- LAST-ACK

  
  
   
    
  
  
  5.  TIME-WAIT   --> <SEQ=101><ACK=301><CTL=ACK>      --> CLOSED

  
  
   
    
  
  
  6.  (2 MSL)
      CLOSED                                                      

  
  
   
    
  
  
                         Normal Close Sequence

  
  
   
    
  
  
                               Figure 13.

 

 

      TCP A                                                TCP B

  
  
   
    
  
  
  1.  ESTABLISHED                                         ESTABLISHED

  
  
   
    
  
  
  2.  (Close)                                              (Close)
      FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  ... FIN-WAIT-1
                  <-- <SEQ=300><ACK=100><CTL=FIN,ACK>  <--
                  ... <SEQ=100><ACK=300><CTL=FIN,ACK>  -->

  
  
   
    
  
  
  3.  CLOSING     --> <SEQ=101><ACK=301><CTL=ACK>      ... CLOSING
                  <-- <SEQ=301><ACK=101><CTL=ACK>      <--
                  ... <SEQ=101><ACK=301><CTL=ACK>      -->

  
  
   
    
  
  
  4.  TIME-WAIT                                            TIME-WAIT
      (2 MSL)                                              (2 MSL)
      CLOSED                                               CLOSED

  
  
   
    
  
  
                      Simultaneous Close Sequence

  
  
   
    
  
  
                               Figure 14.

 

3.6.优先级和安全性

意图是连接只允许在同两个端口要求的优先级和间隔值相等或者更高的情况下在端口间进行。

TCP中使用的优先级和安全参数就是那些在Internet协议(IP)中定义的优先级和安全参数。在这个TCP规范中,术语“安全性/间隔(compartment)”是用来指示用于IP的安全参数,包括安全性(security),间隔(compartment),用户组(user group)和处理限制(handling resetriction

一个有着不匹配的安全/间隔值或者较低优先级值的连接尝试必须通过发送一个reset被拒绝。由于优先级太低拒绝一个连接只发生在SYN的确认收到之后。

注意,仅操作于优先级的缺省值之上的TCP模块仍会检查到来分片的优先级,且可能提高他们用于连接的优先级。

安全参数可以被用于一个非安全环境(值指示了未分类的数据),然后在非安全环境中的主机必须准备接收安全参数,即使他们不需要发送这些参数。

3.7数据通信

一旦连接建立,数据通过分片的交换进行通信。因为分片可能由于错误(校验和测试失败),或者网络拥挤而丢失,TCP使用了重传(经过一个超时)来确保每个分片的投递。由于网络和TCP的重传,可能会有重复分片到达。如系列号一节讨论的,TCP对分片的系列号和确认号码进行某些测试来查证可接受性。

数据发送者在变量SND.NXT中记录了下一个要使用的系列号。接收者在变量RCV.NXT中使用了期待接收的下一个系列号。数据发送者在变量SND.UNA中记录了最老的未经确认的系列号。如果数据流即刻空闲,且所有发送的数据已经被确认,则三个变量相等。

当发送者创建了一个分片并传输它的时候,发送者增加了SND.NXT。当接收者接受了一个分片,他增加了RCV.NXT并发送了一个确认。当数据发送者接收一个确认,它增加了SND.UNA。这三个变量的差值可以用来衡量通信的延迟。变量增加的数量是分片中数据的长度。注意,一旦处于ESTABLISHED状态,所有的分片必须携带当前确认信息。

CLOSE用户调用执行了一个PUSH函数,通过这个函数,在一个到来分片中包含了FIN控制位。

重传超时(Retransmission Timeout

由于组成internetwork系统的网络的多样性和TCP连接的大范围使用,重传超时必须被动态确定。确定重传超时的一个程序在下面给出。

一个重传超时例子程序

计算以一个特殊系列号发送一个数据八位字节和接收到覆盖那个系列号(发送分布不一定要匹配接收到的分片)的确认之间这段流逝时间。这样计算的流逝时间是往返旅行时间(RTTRound Trip Time)。接着计算一个平滑往返旅行时间(SRTTSmoothed Round Trip Time):

SRIT = (ALPHA*SRTT)+((1-ALPHA)*RTT)

基于这个,计算重传超时(RTOretransmission timeout):

RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]]

这里UBOUND是超时上限(比如,1分钟),LBOUND是超时下限(比如,1秒),ALPHA是个平滑因子(比如,.8.9),BETA是一个延迟因子(比如,1.32.0

紧急信息的通信(The Communication of Urgent Information

TCP紧急机制的目的是允许发送用户激发接收用户去接收一些紧急数据并允许接收TCP当所有的当前已知的紧急数据被用户接收的时候去指示接收用户。

这个机制允许数据流中的某个点被指派为紧急信息的结束。不管什么时候当这个点在接收TCP的接收系列号(RCV.NXT)之前,TCP必须告知用户进入“紧急模式(urgent mode)”,当接收系列号追上紧急指针,TCP必须告诉用户进入“正常模式(normal mode)。如果紧急指针在用户处于紧急模式的时候被更新,这个更新对用户是不可见的。

这个方法采用了一个在所有传输分片中传输的紧急字段。URG控制位指示了紧急字段有意义且必须被添加到分片系列号里面来产生紧急指针。如果没有这个标志,则表示没有显著的紧急数据。

要发送一个紧急指示,用户必须发送至少一个数据字节。如果发送用户同时指示了一个push,紧急信息到目的进程的立即投递被加强。

管理窗口(Managing the window

在每个分片中发送的窗口指示了窗口发送者(数据接收者)当前准备接收的系列号的范围。通常假定这是同这个连接的当前可用数据缓冲空间相关的。

指定一个大的窗口可能会加大重传概率。如果多于可以被接受的数据到达,它将被丢弃。这将导致过多的重传,给网络和TCP增加了不必要的负载。指示一个小的窗口可以限制重传,但会在每个新的重传分片之间引入一个往返延迟。

这个机制允许TCP广告一个大的窗口,随后没有接收那么多数据,广告一个小得多的窗口。这也称为“收缩窗口”,是非常令人气馁的.坚固原则规定TCP不会自己收缩窗口,但会对另一端的TCP的这种行为有所准备。

发送TCP必须准备从用户接受并且发送至少一个八位字节的新数据即使发送窗口是0。发送TCP必须有规律地重传给接收TCP即使当窗口是0。当窗口是0时,建议重传间隔为2分钟。重传可以保证任何有一个0窗口的TCP的窗口的重新打开将会可靠地报告给另一端。

当接收TCP有一个0窗口并且分片到达,它必须仍然发送一个确认说明它下一个期待的系列号和当前窗口(0)。

发送TCP将要传输的数据包装成适合当前窗口的分片,且可以在重传队列中重新包装分片。这样的重新包装不要求,但是很有用。

在一个有着单向数据流的连接中,窗口信息将会在确认分片中携带,这些分片具有相同的系列号,因此如果他们不按顺序到达,就没有办法记录他们。

这不是一个严重的问题,但它将允许窗口信息有时临时地基于数据接收者的老的报告。一个避免这个问题的技巧是作用于携带最高的确认号码的窗口信息(也就是那些确认号码等于或者大于之前接收到的最高的确认号码)

窗口管理程序对通信性能有重要影响。下面是一些对实现者的建议。

窗口管理建议

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

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

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

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

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

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

3.8接口(Interfaces

当然,我们关心两组接口:用户/TCP接口和TCP/底层接口。我们有一个用户/TCP接口的相对详细的模型,但是底层协议模块的接口这里没有指定,因为它将由底层协议规范详细指定。在这个例子中,底层是IP,我们列出TCP可以使用了一些参数值。

 

用户/TCP接口

下面对TCP的用户命令描述尽可能地概括式的,因为每个操作系统有不同的接口。从而,我们必须警告读者,不同的TCP实现可能有不同的用户接口。但是,所有的TCP必须提供最少的一套服务接口以保证所有的TCP实现可以支持同样的层次结构。这个部分指定了所有TCP实现要求的功能性接口。

 

TCP 用户命令

下面的章节功能性地描述了一个用户/TCP接口。使用的符号同高级语言里面的大多数程序和接口函数相似,但这个用法不是用来排除圈套类型的服务调用(比如,SVCsUUOsEMTs

下面描述的用户命令指定了TCP必须实现以支持进程间通信的基本功能。各自的实现必须定义他们自己的形式,且可以在一个简单调用中提供基本功能的结合或者子集。特别地,一些实现可能希望自第一个SEND或者RECEIVE调用中自动OPEN一个连接。

要提供进程间通信的接口,TCP不仅要接受命令,还要返回信息给他服务的进程。后一部分包括:

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

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

 

Open

格式:OPEN(本地端口(local port),外部套接字(foreign socket),主动(active)/被动(passive)[,超时(timeout)][,优先级(precedence)][,安全性(security)/分隔(compartment)][,选项(options]à本地连接名字(local connection name

我们假定本地TCP知道他服务的进程的id,并且将检查进程使用指定连接的权利。依赖于TCP的实现,本地网络和源地址的TCP标识将由TCP或者底层协议(比如IP)提供。这些考虑是是安全性考虑的结果,比如没有TCP可以假扮成其它TCP,等等。类似的,没有进程可以假扮成另一个进程,除非同TCP勾结。

如果主动(active/被动(passive)标志被置成被动,则是对LISTEN的调用,对到来的连接进行监听。一个被动的打开可以有一个完全指定的外部套接字来等待一个特定的连接或者一个未指定的外部套接字来等待任何调用,一个完全指定的被动调用可以通过后来的SEND的执行变成主动的。

一个传输控制块(TCB)被创建且部分被从OPEN命令参数得到的数据填充。

在一个主动调用命令里面,TCP将立即开始连接的同步过程(如,建立)。

超时参数,如果出现的话,允许调用者对所有的传输给TCP的数据设定超时。如果数据不在指定的时间间隔被成功投递到目的地,TCP将终止连接。现在的缺省值是5分钟。

TCP或者操作系统的某些部分将验证用户以指定的优先级或者安全性/分隔打开一个连接的权限。如果不在OPEN调用中指定优先级或者安全性/分隔,则采用缺省值。

仅当安全性/分隔信息相同且优先级等于或者高于OPEN调用所要求的优先级,TCP将接受到来的请求。

连接的优先级是OPEN调用所要的值和接收到的到来请求的值的高者,并且在连接的生命周期内固定在那个值。实现者可能希望给用户优先级协商的控制。比如,用户可能允许指定优先级必须严格匹配,或者任何提高优先级的尝试必须由用户确认。

本地连接名字被TCP返回给用户。该名字可以用来作为由《本地套接字,外部套接字》对定义的连接的简称。

Send

格式:SEND(本地连接名字(local connection name),缓冲地址(buffer address),字节数量(bye count),PUSH标志,URGENT标志[,超时(timeout)]

这个调用导致了包含在指定用户缓冲的数据在指定连接被发送。如果连接还没有打开,SEND被认为是一个错误。有些实现可能会允许用户先SEND;在这种情况下,将会自动调用OPEN。如果调用进程没有权利使用这个连接,返回一个错误。

如果设置了PUSH标志,数据必须立刻被传送给接收者,且PUSH位将被设置于从缓冲中创建的最后一个TCP分片。如果PUSH标志没有设置,数据可以同之后的SEND调用的数据结合在一起,以提高传输效率。

如果设置了URGENT标志,发送给目的IP的分片将设置紧急指针。如果紧急指针指示紧急指针之前的数据还没有被接收进程消耗掉的话,接收TCP将向接收进程标记紧急条件。Urgent的目的是激发接收者处理紧急数据,并指示接收者什么时候所有当前已知的紧急数据已经被接收。发送用户标识紧急的次数不一定同接收用户被通知紧急数据出现的次数相等。

如果没有在OPEN中指定外部socket,但是连接建立了(比如,因为一个正在监听的连接由于外部分片到达本地socket变得特殊),则指定的缓冲被发送到隐含的外部socket。以未指定的外部socket使用OPEN的用户可以在不曾明确知道外部soeket的地址的情况下使用SEND

但是,如果SEND在外部socket确定之前被调用,将返回一个错误。用户可以使用STATUS调用来判断连接的状态。在某些实现中,TCP在一个未指定的socket被绑定时可能通知用户。

如果指定了超时,这个连接的当前用户超时将变成新的值。

在最简单的实现中,SEND将不回返回控制给发送进程,直到传输完成或者超时。但是,这种简单的方法可能会导致死锁(比如,连接的两端可能会在做任何RECEIVE之前尽力去SEND)和提供低性能,所以不被推荐。一个比较成熟的实现是立即返回,允许进程同网络I/0同时运行。多个SENDs以先到先服务的顺序被服务,因此TCP将那些它不能马上服务的接口调用放到队列中。我们暗中指定了一个用户接口,通过这个接口,SEND后来会从服务TCP发送某个种类的信号量或者伪中断。一个可以替代的方法是立即返回一个响应。比如,SENDs可能会立即返回一个本地的确认,即使要发送的分片还没有被远端TCP确认。我们乐观地假定事件成功。如果我们错误了,连接将由于超时关闭。在这种同步方式的实现中,也将会有一些异步信号量,但这些信号量将由连接自己处理,而不是由特定的分片或者缓冲。

为了进程能够在不同的SENDs中区分错误或者成功指示,返回缓冲地址和SEND请求的响应编码是比较合适的。将在后面进行讨论的TCP-to-user信号量指示了必须返回给调用进程的信息。

Receive

格式:RECEIVE(本地连接名字(local connection name),缓冲地址(buffer address),字节数(byte count-à字节数(byte count),紧急标志(urgent flag),push标志(push flag

这个命令分配了一个接收缓冲同指定连接联系在一起。如果之前没有OPEN或者调用进程没有权利使用这个连接,会返回一个错误。

在最简单的实现中,控制权将不会返回给调用程序,除非缓冲满了,或者错误发生了,但是这种方式很容易引起死锁。一个比较成熟的实现是允许几个RECEIVEs同时出现。当分配到达的时候,相应的缓冲就被填充。这个策略允许以更加复杂的架构(可能是异步的)来通知调用程序PUSH已经被发送或者缓冲填满的代价来增加吞吐量。

如果足够充满返冲的数据在PUSH发现之前到达,PUSH标志将不会被设置来响应RECEIVE。缓冲将填充尽可能多的数据。如果PUSH标志在缓冲满之前发现,缓冲将在部分满的情况下返回,并指示PUSH标志。

如果有紧急数据,紧急数据一到达,将通过一个TCP-to-user的信号通知用户。然后接收用户就进入紧急模式(urgent mode)。如果URGENT标志打开,额外的紧急数据保留着。如果URGENT标志关闭,RECEIVE的调用返回所有的紧急数据,用户可能现在离开紧急模式(urgent mode)。注意跟在紧急指针后面的数据(非紧急数据)不能在同一块缓冲里面同前面的紧急数据被投递给用户,除非边界被清晰地标注。

为了区分几个显著的RECEIVEs以及照顾到缓冲没有被完全充满的情况,缓冲指针和一个指示真正收到的数据的真实长度的字节数同返回码一起返回。

一个RECEIVE的替代的实现可能由TCP分配缓冲,或者TCP可以同用户共享一个环型缓冲。

Close

格式:CLOSE(本地连接名字(local connection name))

这个命令将关闭指定的连接。如果连接没有打开或者调用进程没有权利使用该连接,将返回一个错误。关闭连接是个优雅的操作,所有的那些显著的SENDs将会被发送(和重传),直到所有都被服务。因此,在一个CLOSE之后进行几次SEND调用是可以被接收的,且期望所有的数据被发送到目的地。也要清楚用户必须继续在一个CLOSING的连接上RECEIVE,因为另一端可能正在发送剩下的数据。因此,CLOSE意思是“我没有数据要发送”,而不是“我不再接收任何数据”。有可能正在关闭的一端无法在超时前清除所有的数据(如果用户级别协议没有经过仔细考虑的话)。在这种情况下,CLOSE转入ABORT,正在关闭的TCP放弃。

用户可能在任何时候主动CLOSE连接,或者响应从TCP到来的各种提示(比如,远端关闭执行了,传送超时,目的地无法到达)

因为关闭一个连接需要同外部TCP通信,连接可以保留在CLOSING状态一小段时间。在TCP回复CLOSE命令前尝试重新打开一个连接将导致错误响应。

关闭也暗示了一个push功能。

Status

格式:STATUS(本地连接名字(local connection name))à状态数据

这是依赖于实现的用户命令,可以被排除,没有不利的影响。返回的信息通常来自于同连接联系的TCP

这个命令返回一个数据块,包含下面的信息:

本地socketlocal socket),

外部socketforeign socket),

本地连接名字(local connection name),

接收窗口(receive window),

发送窗口(send window),

连接状态(connection state),

等待确认的缓冲的数目(number of buffers awaiting acknowledgment),

等待接收的缓冲数目(number of buffers pending receipt),

紧急状态(urgent state),

优先级(precedence),

安全性/分隔(security/compartment)

传送超时(transmission timeout

基于连接的状态或者实现本身,有些信息可能无法获取或者没有意义。如果调用进程没有权利使用这个连接,将返回一个错误。这防止了未授权进程获取关于连接的信息。

Abort

格式:ABORT(本地连接名字(local connection name))

这个命令将放弃所有悬而未决的SENDsRECEIVEsTCB被清除,特殊的RESET信息将被发送给连接另一端的TCP。依赖于实现,用户可能接收到每个显著的SEND或者RECEIVE的指示,或者可能只是收到一个ABORT确认。

TCP-to-User信息

假定操作系统为TCP提供了一个异步发送信号给用户程序的方法。当TCP发信号给用户程序的时候,一些信息传给了用户。在规范中,信息通常会是一个错误信息。在其它情况下,有可能是相关于执行SEND或者RECEIVE或者其它用户调用的完成情况的信息。

下面的信息被提供:

本地连接名字(Local Connection Nmae                总是提供


响应字串(Resonse String)                              总是提供

缓冲地址(Buffer Address)                              Send & Receive

字节个数(Byte Cound(Counts bytes received))              Receive

Push标志                                            Receive

Urgent标志                                          Receive

 

TCP/底层协议 接口

TCP调用一个底层协议模块来在网络上接收和发送信息。在ARPA 互联网系统中,底层协议是Internet协议(IP

如果底层级别的协议是IP,它提供了服务类型(type of service)和生存时间(time to live)等参数。TCP对于这些参数使用了下列设置:

Type of Service = Precedence(优先级):routine(常规),Delay(延迟):normal(正常),Throughput(吞吐量):normal(正常),Reliability(可靠性):normal(正常);or 00000000

Time to Live(生存时间) = 1分钟,或者00111100

注意假定最大分片生命周期是2分钟。这里我们明确要求分片如果在1分钟内不能被投递,它必须被销毁。

如果底层协议是IP(或者其它提供这个特性的协议),且使用源地址选路,接口必须允许选路信息进行通信。这特别重要,因为这样保证在校验和中使用的源地址和目的地址是初始的源和最后的目的地址。保留返回路径来响应连接请求也很重要。

任何底层协议需要提供源地址,目的地址和协议字段,以及一种确定“TCP长度”的方式,既可以提供功能性的等同IP服务,也可以在TCP检验和中使用。

3.9 事件处理(Event Processing

本章节描述的处理是一种可能实现的例子。其它实现可能在处理顺序上略有不同,但是他们仅在细节上有不同的地方,而不是本质上。

TCP的活动可以被概括为对事件的响应。发生的事件可以分为三种类型:用户调用(user calls),分片到达(arriving segments),和超时(timeouts)。本章节描述TCP响应这些事件所做的处理。在很多情况下,处理需要依赖于连接的状态。

发生的事件:

用户调用

OPEN

SEND

RECEIVE

CLOSE

ABORT

STATUS

到来分片

SEGMENT ARRIVES

超时

用户超时(USER TIMEOUT

重传超时(RETRANSMISSION TIMEOUT

时间等待超时(TIME-WAIT TIMEOUT

TCP/用户接口的模型是用户命令接收到一个立即返回且可能有一个通过事件或者伪中断的延时响应。在下面的描述中,术语“信号(signal)”意味着导致了一个延时响应。

错误的响应以字符串的形式给出。比如,执行一个不存在的连接的命令收到“error:connection

not open”

请注意下面所有同系列号,确认号码,窗口等相关所有算法,都是对系列号空间大小进行模2**32。同时注意”=<”标识小于或者等于(2**32)

一个处理到来分片的自然的方式是想像他们首先测试是否是正确的系列号码(比如,他们的内容在系列号空间上是否位于期望的“接收窗口”范围内)然后他们通常被放入队列中,以系列号顺序被处理。

当一个分片同其它已经接收到的分片交迭在一起,我们重建分片,仅包含新的数据,然后调整头部字段以保持一致。

注意如果没有提到状态改变,TCP停留在同一个状态。

 

OPEN调用

  CLOSED状态(如,TCB不存在)

创建一个新的传输控制块(TCB)来保存连接状态信息。填充本地socket标识,外部
    socket
,优先级,安全性/分隔(compartment)和用户超时信息。注意有些外部socket可能

在一个被动的OPEN调用里没有被指定,且将在到来SYN分片的参数里面被填充。允

许用户验证所要求的安全性和优先级,如果不满足返回“error:  precedence not allowed”或者“errorsecurity/compartment not allowed“。如果是被动的,进入LISTEN状态,返回。如果是主动的,且外部socket没有被指定,返回”error: foreign socket unspecified;如果是主动的,且外部socket指定了,发起一个SYN分片。选择一个初始的发送系列号码(ISSinitial send sequence number)。一个<SEQ=ISS><CTL=SYN>形式的SYN分片被发送。设置

SND.UNAISS,SND.NXTISS+1,进入SYN-SENT状态,返回。

如果调用者没有访问指定的本地socket的权利,返回“错误:连接对该进程非法

connection illegal for this process。如果没有空间创建一个新的连接,返回错误:

资源不足(insufficient resources

 LISTEN状态

如果是主动方式且指定了外部socket,则将连接从被动改成主动,选择一个ISS。发送

一个SYN分片,设置SND.UNAISSSND.NXTISS+1。进入SYN-SENT状态。

SEND联系在一起的数据可以同SYN分片一起发送或者放到队列中,在进入

ESTABLISHED状态后发送。如果在命令中包含紧急位,紧急位必须同该命令的数据分

片一起被发送。如果没有空间来将请求放入队列,响应错误:资源不足(insufficient

resources)”。如果外部socket没有指定,返回“错误:外部socket未指定(foreign socket

unspecified)”

SYN-SENT STATE

SYN-RECEIVED STATE

ESTABLISHED STATE

FIN-WAIT-1 STATE

FIN-WAIT-2 STATE

CLOSE-WAIT STATE

CLOSING STATE

LAST-ACK STATE

TIME-WAIT STATE

返回错误:连接已经存在(connection already exists”.

 

SEND调用

CLOSED状态(比如,TCB不存在)

   如果用户没有访问这个连接的权限,返回”error:connection illegal for this process”.

   否则,返回”error:connection does not exist”.

LISTEN状态

   如果指定了外部socket,则将连接从被动改成主动,选择一个ISS。发送一个SYN

   分片,将SND.UNA设置成ISSSND.NXT设置成ISS+1。进入SYN-SENT状态。

   SEND联系的数据可以同SYN分片一起发送,或者放到队列中,进入

ESTABLISHED状态后发送。如果命令中要求了紧急位,紧急位必须同命令的数据

分片一起发送。如果没有空间将请求放到队列中,响应“errorinsufficient resources”

如果外部socket未指定,返回”err:foreign socket unspecified”

SYN-SENT状态
    SYN-RECEIVED
状态

   将数据放到队列中,进入ESTABLISHED状态后发送。如果队列中没有空间,响

”error:insufficient resources”

ESTABLISHED状态

CLOSE-WAIT状态

  将缓冲组装成分片,发送该分片和一个确认(确认值=RCV.NXT)。如果没有足够的

空间来记录这个缓冲,简单地返回”error:insufficient resources”

如果设置了紧急标志,则SND.UP<-SND.NXT-1,并在外出分片中设置紧急指针。

    FIN-WAIT-1 状态

    FIN-WAIT-2状态

    ClLOSING状态

    LAST-ACK状态

    TIME-WAIT状态

      返回”error:connection closing”,不服务请求。

 

RECEIVE调用

CLOSED状态(比如,TCB不存在)

   如果用户没有访问这个连接的权限,返回”error:connection illegal for this process”.

   否则,返回”error:connection does not exist”.

  LISTEN状态

  SYN-SENT状态

  SYN-RECEIVED状态

       放到队列中,等到TCB进入ESTABLISHED状态后处理。如果队列中没有空间放置该请求,响应”error: insufficient resource”

   ESTABLISHED状态

FIN-WAIT-1 状态

   FIN-WAIT-2状态

       如果没有充足的分片在队列中来满足请求,将请求放到队列中。如果没有队列空间来记住RECEIVE,响应”error: insufficient resource”.
重新组装在队列中的到来分片,放到接收缓冲中,返回给用户。如果发现PUSH标志,标记“push seen

       如果RCV.UP在当前传给用户的数据之前,通知用户紧急数据的存在。

       TCP负起了投递数据给用户的责任,必须通过发送一个确认来告诉发送者。确认的组成在下面处理到来分片中描述。

  CLOSE-WAIT状态

     因为远端已经发送了FINRECEIVEs必须被已经在手上的文本满足,但不投递给用

户。如果没有文本等待投递,RECEIVE将获得“error:connection closing “响应。否则,

任何还保留的文本可以用来满足RECEIVE

   CLOSING 状态

   LAST-ACK 状态

   TIME-WAIT状态

     返回”error:connection closing”

 

CLOSE调用

   CLOSED状态(如,TCB不存在)

     如果用户没有权限访问这个连接,返回“error:connection illegal for this process”.

     否则,返回”error:connection does not exist”

   LISTEN状态

     任何显著的RECEIVEs都会返回“error:closing”响应。删除TCB,进入CLOSED状态,

返回

   SYN-SENT状态

     删除TCB,返回”error:closing”响应给任何队列中的SENDs,或者RECEIVEs

   SYN-RECEIVED状态

     如何没有SENDs被发起且没有悬而未决的数据要发送,则组装一个FIN分片并发送

它,然后进入FIN-WAIT-1状态,否则放到队列中,在进入ESTABLISHED后处理。

   ESTABLISHED状态

     放到队列中,在所有的SENDs组装发送后,组装一个FIN分片并发送它。任何情况

下,进入FIN-WAIT-1状态。

   FIN-WAIT-1状态

   FIN-WAIT-2状态

     严格地说,这是一个错误,将收到”error:connection closing”响应。一个“ok”响应也可以被接受,只要第二个FIN没有被发送(但第一个FIN可能被重传)

   CLOSE-WAIT状态

     将请求放到队列中,直到所有之前的SENDs被组装成分片,然后发送一个FIN分片,进入CLOSING状态。

   CLOSING状态

   LAST-ACK状态

   TIME-WAIT状态

      响应“errorconnection closing

 

ABORT调用

   CLOSE状态(比如,TCB不存在)

      如果用户没有权限访问这个连接,返回“error:connection illegal for this process”.

      否则,返回”error:connection does not exist”

   LISTEN状态

     任何显著的RECEIVEs都会返回“error:closing”响应。删除TCB,进入CLOSED状态,

返回

  SYN-SENT状态

      给所有的队列中的SENDsRECEIVEs发送“connection reset”通知,删除TCB,进入CLOSED状态,返回

  SYN-RECEIVED

  ESTABLISHED

  FIN-WAIT-1

  FIN-WAIT-2

  CLOSE-WAIT状态

     发送一个reset分片:

     <SEQ=SND.NXT><CTL=RST>

     给所有的队列中的SENDsRECEIVEs发送“connection reset”通知.所有等待传输(除了上面所述的RST)和重传的分片被清空,删除TCB,进入CLOSED状态,返回。

  CLOSING

  LAST-ACK

  TIME-WAIT

     响应“ok”,删除TCB,进入CLOSED状态,返回

 

STATUS调用

  CLOSED状态(如,TCB不存在)

     如果用户没有权限访问这个连接,返回“error:connection illegal for this process”.

     否则,返回”error:connection does not exist”

  LISTEN状态

     返回”state=LISTEN”,返回TCB指针

  SYN-SENT 状态

     返回”state=SYN-SENT”,返回TCB指针

  SYN-RECEIVED状态

     返回”state=SYN-RECEIVED”,返回TCB指针

  ESTABLISHED状态

     返回”state=ESTABLISHED”,返回TCB指针

  FIN-WAIT-1状态

     返回”state=FIN-WAIT-1”,返回TCB指针

  FIN-WAIT-2状态

     返回”state=FIN-WAIT-2”,返回TCB指针

  CLOSE-WAIT状态

     返回”state=CLOSE-WAIT”,返回TCB指针

  CLOSING状态

     返回”state=CLOSING”,返回TCB指针

  LAST-ACK状态

     返回”state=LAST-ACK”,返回TCB指针

  TIME-WAIT状态

     返回”state=TIME-WAIT”,返回TCB指针

 

分片到达

   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.NXTSEG.SEQ+1IRS设置成SEG.SEQ,其它的控制或者文本被放到队列中以后处理。ISS必须被选择,一个如下形式的SYN分片被发送:

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

SND.NXT被设置成ISS+1SND.UNA设置成ISS。连接状态必须被改成SYN-RECEIVED.注意任何其它的到来控制或者数据(同SYN结合)将在SYN-RECEIVED状态被处理,但是不用重复处理SYNACK。如果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.NXTACK可以被接受

第二,   检查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
这一步只有当ACKok的时候才需要,或者当没有ACK,且分片不包含一个RST
如果SYN位打开,且安全性/分隔和优先级可以被接受,则设置RCV.NXTSEG.SEQ+1,设置IRSSEG.SEQSND.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状态后进行处理,返回。

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

 

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.WND0,则不能接受分片,但是合法的ACKsURGsRSTs例外。

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

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

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

接下来的例子假定分片是一个理想化的分片,它开始于RCV.NXT,没有超过窗口。可以通过去掉任何位于窗口之外的部分(包括SYNFIN)对真正的分片进行剪裁以满足这个假设,且仅当分片开始于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位,则任何显著的RECEIVEsSEND都会收到“reset”响应。所有分片队列都会被清空。用户也会接收一个未被恳求的“connection reset”信号。进入CLOSED状态,删除TCB,返回。

     CLOSING状态

     LAST-ACK状态

TIME-WAIT状态

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

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

     SYN-RECEIVED

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

         发送一个reset,返回

     ESTABLISHED状态

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

送一个reset,任何显著的RECEIVEsSEND将接收到“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.SEQSND.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.NXTRCV.WND的总值不能被减少。

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

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

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

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

    CLOSE-WAIT STATE

    CLOSING STATE

    LAST-ACK STATE

    TIME-WAIT STATE

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

第八步,检查FIN

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

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

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

同一条信息,提高RCV.NXTFIN,发送一个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

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

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

状态并返回

 

重传超时(RETRANSMISSION TIMEOUT

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

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

 

TIME-WAIT超时

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

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值