II. 协议
NWG/RFC #33 中阐述的连接概念贯穿整个协议。连接是一条单工通信路径, 旨在连接两个进程。
协议的主要功能是提供: (1)连接的建立, (2)连接上流量的调节, 以及(3)连接的终止。
此外, 协议还提供一些辅助功能, 例如发送模拟中断脉冲和回显测试消息。
为提供一条交换连接相关信息的路径, 我们指定特定的链路, 即每对主机之间的链路 1, 作为控制链路。控制链路上的流量仅由下文定义的控制命令构成。
连接由一对套接字命名。套接字是全网已知的 40 位名称。每台主机分配到这些名称中的一个私有子集, 请求连接的命令会指明一个位于请求主机本地的套接字和一个位于请求接收方本地的套接字。
套接字具有极性: 偶数编号的套接字为接收套接字, 奇数编号的为发送套接字。建立一个连接需要各一个。
为便于通过连接传输信息, 每个连接都分配有一条唯一的链路。因此, 建立连接的步骤之一就是分配链路。在非控制链路中, 链路 0 保留供网络内部使用, 链路 32 至 255 保留用于实验和扩展。因此, 只有链路 2 至 31 可供常规使用。链路分配要么始终由接收方完成, 要么始终由发送方完成。我们(几乎)任意地选择由接收方负责。
所有常规消息均由 32 位报文首部、标记、文本和填充组成。标记是一串(可能为空的)零后跟一个 1;填充是一个 1 后跟一串(可能为空的)零。
通过控制链路(链路 1)发送的常规消息称为控制消息。其文本由整数个(可能为零个)按下文所述格式编写的控制命令组成, 且该文本必须在命令边界处结束。
用于建立连接的命令是 STR 和 RTS。STR 命令由预期的发送方发往预期的接收方。其 <my socket> 字段包含预期发送方本地的一个发送套接字;其 <your socket> 字段包含预期接收方本地的一个接收套接字。RTS 命令与之对偶, 但还包含一个用于链路分配的 <link> 字段。这两个命令统称为连接请求(RFC)。如果一个命令的 <my socket> 字段与另一个命令的 <your socket> 字段相同, 反之亦然, 则该 STR 与 RTS 相匹配。当双方交换了一对相匹配的 RFC 后, 连接即告建立。
主机不得对任何本地套接字建立多于一个连接。因此, 如果某个套接字已在先前的 RFC 中被提及且该连接尚未终止, 主机就不得将该套接字用于 RFC 的 <my socket> 字段。
用于终止连接的命令是 CLS。在连接完全终止、套接字可以自由参与其他连接之前, 每一方都必须发送并接收一个 CLS 命令。在终止连接之前, 并不要求双方的 RFC 都已交换。有关终止的更多细节见下文。
连接建立后, 接收主机发送一个 ALL 命令, 为该连接分配空间。如前所述, 发送方跟踪接收主机中可用空间的大小, 传输的文本不超过接收主机能够接受的量。此外, 本地 IMP 也对发送方有所限制: 在收到上一条消息的 RFNM 之前, 不得通过该连接发送消息。
连接建立后, 由接收方和发送方发出的 CLS 命令效果略有不同。发送方发出的 CLS 命令表示不会再通过该连接发送任何消息。如果该连接上有消息正在传输, 则不得发送此命令。
接收方发出的 CLS 命令相当于要求发送方终止传输。但由于 CLS 命令送达发送方存在延迟, 接收方必须预期其缓冲区会被填满至 ALL 命令所给出的上限。
在连接已建立期间, 任一方都可以发送 INR 或 INS 命令。这些命令的解释属于本地事务, 但一般而言它们将提供一个转义功能。
注意, ALL、INR 和 INS 命令只能在连接建立之后、发送 CLS 命令之前发送。
ECO 和 ERP 命令提供了一种非常简单的测试手段。主机收到 ECO 命令后, 必须将其前八位改为 ERP 并将其返回。这些命令与连接无关。
为方便起见, 协议包含了一个 NOP 命令。它被编码为零, 以便于构造命令消息。
最后, 协议包含一个 ERR 命令, 用于通知外部主机它(显然)出了错。目前尚未定义具体的错误列表, 也未定义收到 ERR 命令时应采取的动作。主机收到 ERR 命令时应将其记入日志, 以便系统程序员诊断问题。主机可以在任何时间、出于任何原因生成 ERR 命令, 但建议每台主机公布一份完整列表, 列出其可能发送的 ERR 命令及其解释。
网络控制命令
下面详细说明每个控制命令的结构和格式。
为便于并明确地描述套接字, 采用以下约定:
命令描述中使用 <my socket> 和 <your socket>。
<my socket> 位于命令发起方本地。
<your socket> 位于命令接收方本地。
控制命令格式
空操作
_______
| |
| NOP |
|_______|
请求连接, 接收方至发送方
______________________________________________
| | | | |
| RTS | my socket | your socket | link |
|_______|_____________|_______________|________|
请求连接, 发送方至接收方
_____________________________________
| | | |
| STR | my socket | your socket |
|_______|_____________|_______________|
关闭
_____________________________________
| | | |
| CLS | my socket | your socket |
|_______|_____________|_______________|
分配
__________________________
| | | |
| ALL | link | space |
|_______|________|_________|
由接收进程发出的中断
_______________
| | |
| INR | link |
|______|________|
由发送进程发出的中断
_______________
| | |
| INS | link |
|______|________|
回显请求
____________________________ _________
| | \ \ |
| ECO | length / / text |
|_______|____________________\ \________|
回显应答
____________________________ _________
| | \ \ |
| ERP | length / / text |
|_______|____________________\ \________|
检测到错误
____________________________ _________
| | \ \ |
| ERR | length / / text |
|_______|____________________\ \________|
主机在报文首部中指定。
<link> 为 8 位
<space> 长 32 位, 为无符号整数。
<length> 为 16 位无符号整数。
<text> 的长度与 length 相同。因此, 该命令比 length 长 24 位。最大长度为一条消息, 以便于命令的解码和处理。
所有控制命令码均为 8 位长:
NOP = 0
RTS = 1
STR = 2
CLS = 3
ALL = 4
INR = 5
INS = 6
ECO = 7
ERP = 8
ERR = 9
<my socket> 和 <your socket> 均为 32 位长,
_______________________
| | |
| User number | AEN |
|_______________|_______|
其中 24 位为用户号, 8 位为 AEN。