📄 tcp协议规范.htm
字号:
<P align=justify>Receive</P>
<P align=justify>格式: RECEIVE (local connection name, buffer address, byte
count) -> byte count, urgent flag, push flag</P>
<P
align=justify>此命令分配一个接收缓冲区给指定的连接。如果下面不是一个OPEN命令或者此调用进行未被授权使用此连接返回错误。最简单的实现方法是在缓冲区没有填充完以前不返回控制权,但这样可能会造成严重的死锁。更复杂的实现方法允许同时存在多个RECEIVE,这样会提高效率。这样是在控制复杂的情况下取得了高效率。</P>
<P
align=justify>如果在PUSH之前的数据已经填满缓冲区,那么对于RECEIVE的响应中就不用设置PUSH位了。缓冲区会容纳尽可能多的数据,如果在缓冲区填充满以前看到PUSH位,将返回缓冲区中的数据并设置PUSH。在处理紧急状态时,如果有URGENT标记,还有紧急数据;如果没有URGENT标记了,就返回所有紧急数据,用户也离开紧急状态。请注意,在紧急指针指向的点以后的那些数据不能和紧急数据一起返回,即使它们在同一个缓冲区内,当然,如果用户指定要这么做例外。</P>
<P
align=justify>为了区别多个RECEIVE并保证缓冲区不被充满,返回的数据中也要包括缓冲区指针和一个计数器指明现在接收了多少数据。RECEIVE可以有自己专用了缓冲区,也可以和用户共享一个缓冲区。</P>
<P align=justify>Close</P>
<P align=justify>格式: CLOSE (本地连接名)</P>
<P
align=justify>此命令关闭连接,如果连接未打开,或未授权可以关闭连接返回错误。在关闭的时候应该注意正常关闭,让所有的发送都发送完数据,也可以如上所说在CLOSE后面加上几个SEND,这就要求用户在收到CLOSE后仍然要进行接收。因此,CLOSE意指“我没有更多的数据要发了”,并不代表“我不再发送任何数据了”。关闭方也可能在超时前不能发出所有数据,这种情况下,要由CLOSE转入ABORT状态。用户可以自己决定在任何时间关闭连接,也可以根据TCP返回的提示关闭。因此关闭操作要和外TCP进行通信,因此在关闭状态可能要呆一会儿,在CLOSE没有返回前调用打开,会返回错误。</P>
<P align=justify>Status</P>
<P align=justify>格式: STATUS (本地连接名) -> status data</P>
<P
align=justify>这个命令和具体的实现有关,而且有可能会有负作用。返回的信息通常来自有连接相关的TCB。返回的数据块中包括下面的信息:本地套接字,外套接字,本地连接名,接收窗口,发送窗口,连接状态,等待确认的缓冲区数,等待接收的缓冲区数,紧急状态,优先级,security/compartment和传输超时。因此实现不同,所以上述数据项中可能有几项没有意义或根本不存在。如果调用进程没有被授权使用这一连接,返回错误。这一点会防止未被授权的进程获得连接状态。</P>
<P align=justify>Abort</P>
<P align=justify>格式: ABORT (本地连接名)</P>
<P
align=justify>此命令中止所有SEND和RECEIVE,删除TCB,将发送特殊的RESERT信息到对方TCP。具体的返回信息会因实现不同而不同。</P>
<P align=justify>TCP到用户信息</P>
<P
align=justify>假定操作系统提供一种可以使TCP异步传送信息到用户程序的机制。当TCP确实通知用户程序时会返回一些特定的信息。通常在这些信息中也会有错误信息,在其它情况下会有关于完成SEND或RECEIVE或其它用户调用的相关信息。会提供下面的几种消息:</P>
<P align=justify>本地连接名 都提供 </P>
<P align=justify>响应串 都提供 </P>
<P align=justify>缓冲区地址 发送和接收 </P>
<P align=justify>字节记数 接收</P>
<P align=justify>Push标记 接收 </P>
<P align=justify>Urgent标记 接收 </P>
<P align=justify> </P>
<P align=justify>TCP和下层接口</P>
<P
align=justify>TCP实际上调用下层服务才能在网络上传输数据,在互联网上我们通常认为TCP的下层是IP协议。如果下层是IP层,它提供一些类于服务类型和生存时间的参数。TCP使用这些参数的如下设置:</P>
<P align=justify>Type of Service = Precedence: routine, Delay: normal,
Throughput: normal, Reliability: normal;或是数字00000000。</P>
<P align=justify>Time to Live = 一分钟,或是数字00111100。</P>
<P align=justify>请注意:假定的最大数据段的生存时间为2分钟,这里人为指定为1分钟。</P>
<P
align=justify>如果下层是IP而且使用源地址路由,接口必须允许路由信息的通信。这对建立连接和进行路由是十分重要的。当然也可以不使用IP协议作为TCP的底层协议,但无论下层协议是什么,都必须提供源地址,目的地址和协议域,以及一些决定TCP长度的域,总之一句话,要能够提供类似于IP的功能。</P>
<P align=justify>3.9. 事件处理</P>
<P
align=justify>下面说明的过程是可能的实现,其它实现和本例的过程可能有一点点不同,但只在细节,而决不在结果。TCP的活动可以总结为对事件的响应。事件可以分为三类:用户调用,接收数据段和超时。下面描述的是TCP对具体事件的响应,在许多情况下,相关的动作(响应)要和连接状态相关。</P>
<P align=justify>用户调用的有:</P>
<P align=justify>OPEN</P>
<P align=justify>SEND</P>
<P align=justify>RECEIVE</P>
<P align=justify>CLOSE</P>
<P align=justify>ABORT</P>
<P align=justify>STATUS</P>
<P align=justify>接收数据段的有:</P>
<P align=justify>SEGMENT ARRIVES</P>
<P align=justify>超时的有:</P>
<P align=justify>USER TIMEOUT</P>
<P align=justify>RETRANSMISSION TIMEOUT</P>
<P align=justify>TIME-WAIT TIMEOUT</P>
<P align=justify>TCP对用户的响应可能是立即的也可能是延时的。错误信息以字符串的形式给出。下面就是一个具体的错误信息:error:
connection not
open。另外,请记住序列号空间大小为2的32次方。处理数据段的顺序为首先接收,再检查序列号,如果是要接收的就放入接收队列。另外,没有说明状态转移时,TCP保持原来的状态。</P>
<P align=justify>OPEN调用</P>
<P align=justify>CLOSED状态</P>
<P
align=justify>创建新的TCB保存连接状态信息,填充本地套接字标记,外套接字,优先级,security/compartment和用户超时信息。注意一部分外套接字在被动OPEN中可能未说明。如果是主动的,而外套接字未指定,返回"error:
foreign socket
unspecified";如果是主动的,而外套接字指定了,发送一个SYN数据段。选择初始发送序列号ISS。SYN数据段的格式如下<SEQ=ISS><CTL=SYN>,设置SND.UNA为ISS,SND.NXT为ISS+1,进行SYN-SENT状态,然后返回。</P>
<P align=justify>如果调用者不能访问指定的本地套接字,返回"error: connection illegal for this
process"。如果没有空间接收新的连接,返回"error: insufficient resources"。</P>
<P align=justify>LISTEN状态</P>
<P
align=justify>如果处于主动状态,指定了外套接字,可以将连接从被动改为主动,并选择ISS。发送一个SYN数据段,设置SND.UNA为ISS,SND.NXT为ISS+1。进入SYN-SENT状态。和SEND一起的数据可以和SYN数据段一起发送,也可以在进入ESTABLISHED状态后发送。如果没有空间接收请求,返回"error:
insufficient resources"。如果未指定外套接字,返回"error: foreign socket
unspecified"。如果处于以下状态:SYN-SENT状态,SYN-RECEIVED,ESTABLISHED状态,FIN-WAIT-1状态,FIN-WAIT-2状态,CLOSE-WAIT状态,CLOSING状态,LAST-ACK状态或TIME-WAIT状态时返回"error:
connection already exists"。</P>
<P align=justify>SEND调用</P>
<P align=justify>CLOSED状态</P>
<P align=justify>如果用户无权访问连接,返回"error: connection illegal for this
process"。否则返回"error: connection does not exist"。</P>
<P align=justify>LISTEN状态</P>
<P
align=justify>如果指定了外套接字,可以将连接从被被动改为主动,选择一个ISS。发送SYN数据段,设置SND.UNA为ISS,SND.NXT为ISS+1。进入SYN-SENT状态。和SEND一起的数据可以和SYN数据段一起发送,也可以在进入ESTABLISHED状态后发送。如果没有空间接收请求,返回"error:
insufficient resources",如果未指定外套接字,则返回"error: foreign socket
unspecified"。</P>
<P align=justify>SYN-SENT状态和SYN-RECEIVED时</P>
<P align=justify>在进入ESTABLISHED状态后将需要传送的数据加入队列。如果队列已无空间,则返回"error:
insufficient resources"。</P>
<P align=justify>ESTABLISHED状态和CLOSE-WAIT状态</P>
<P align=justify>将缓冲区分段,发送缓冲区数据,并使它带有确认值RCV.NXT。如果没有空间保存缓冲区,则返回"error:
insufficient resources"。如果设置了紧急标记,那么SND.UP <-
SND.NXT-1,并设置紧急指针指向发送数据段中的相应位置。</P>
<P
align=justify>在FIN-WAIT-1,FIN-WAIT-2,CLOSING,LAST-ACK和TIME-WAIT状态时返回"error:
connection closing",不理会请求。</P>
<P align=justify>RECEIVE调用</P>
<P align=justify>CLOSED状态</P>
<P align=justify>如果用户没有权利访问这个连接,返回"error: connection illegal for this
process"。如果有权利,则返回"error: connection does not exist"。</P>
<P align=justify>在LISTEN,SYN-SENT和SYN-RECEIVED状态下</P>
<P align=justify>在进入ESTABLISHED状态后,将数据放入队列准备处理。如果队列中没有空间,返回"error:
insufficient resources"。</P>
<P align=justify>在ESTABLISHED,FIN-WAIT-1和FIN-WAIT-2状态下</P>
<P align=justify>如果没有接收到足够的数据段满足请求,将请求放入队列。如果队列中没有空间记录RECEIVE,返回"error:
insufficient
resources"。重新将接收数据段放入接收缓冲区,并返回给用户。在这种情况下,可以设置PUSH标记。如果RCV.UP比现在传送给用户的要大,通知用户有紧急数据。</P>
<P align=justify>CLOSE-WAIT状态</P>
<P
align=justify>因为远方TCP已经发送了FIN,RECEIVE必须由现在在缓冲区但还未传送给用户的数据满足。如果没有数据了,RECEIVE会得到"error:
connection closing"的响应。</P>
<P align=justify>在CLOSING,LAST-ACK和TIME-WAIT状态下返回"error: connection
closing".</P>
<P align=justify> </P>
<P align=justify>CLOSE 调用</P>
<P align=justify>CLOSED状态</P>
<P align=justify>如果用户没有权利访问这个连接,返回"error: connection illegal for this
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -