用户-用户协议(提案)
以下协议旨在适用于消息中标记位结束与填充位开始之间的那些数据位。现行的 IMP-IMP 与 HOST-HOST 协议不受本提案影响。
总的原则是,每一段(这不是一个技术术语)数据之前都有说明其性质与范围的控制信息。这一基本方案是从 SOS 缓冲系统所使用的方法演化而来的(参见 JACM 1959 年 4 月的那几篇论文,尤其是 O.R. Mock 的那一篇)。
我们的观点是,链路是信息的载体。信息以固定最大长度的段来承载,这些段称为_消息_[1]。从用户的角度看,事情竟然如此纯属偶然;当用户想要传送一段连续的数据流时,他通常会以(从 IMP-IMP 或 HOST-HOST 协议的角度看)不同的方式来分段——我们把他分的段称为_记录_。应当清楚,这完全类似于(物理)_块_与(逻辑)记录这两个概念之间的关系。此外,文件存储系统也会利用控制信息与状态信息;我们也将如此。
在 USER-USER 协议一级,经由链路传输的一切信息都是标志的序列,其后跟(可能为空的)数据块。
一般格式如下:
OPERATION COUNT DATA
OPERATION 字段总是存在,长度为四位。COUNT 字段在存在时给出其后数据块中的数据字节数。字节大小由最近一个在先的 SIZE 标志设定(在大多数情况下)。字节长度可以在零到 255 位之间(是的,Virginia,即便你有一台 System/360,零也还是零)。OPERATION 字段与 COUNT 字段(在存在时)称为标志,数据字节(在存在时)称为数据块。后跟数据块的标志(即使由于计数为零而为空)称为块标志,其他标志称为 whyte[2]标志。
应当注意,由于 SIZE 标志为随后的各个块设定字节大小,字节大小既可以按发送 HOST 的“自然”大小来设定,也可以按接收 HOST 的“自然”大小来设定,取决于发送与接收进程之间的本地约定。特别要求:在每个消息中,SIZE 标志必须出现在任何块标志(ASCII 标志除外)之前;SIZE 标志可以由实现该协议的例程按默认方式引入,其部分用意是作为检测某些类别错误的一种手段。
COUNT 字段长度为 8 位(EOM 标志中除外,那里它是 16 位长)。各标志如下:
Whyte 标志
| 标志 | 名称 | 含义 |
|---|---|---|
| 0 | NUL | 无操作(考虑下一个标志) |
| 1 | RS | 记录分隔符(记录结束) |
| 2 | GS | 组分隔符(组结束) |
| 3 | FS | 文件分隔符(文件结束) |
| 4 | ESC | 转义到标志的本地约定 |
| 5 | (保留供以后分配) | |
| 6 | EOM N | 消息结束(N 为总位数) |
| 7 | SIZE N | 字节大小为 N 位 |
| 8 | IGNORE N | 忽略随后的数据位 |
块标志
| 标志 | 名称 | 含义 |
|---|---|---|
| 9 | SYS N | N 个字节的数据,供接收 HOST 系统使用 |
| 10 | CONTROL N | 随后有 N 个字节的控制数据 |
| 11 | STATUS N | 随后有 N 个字节的状态数据 |
| 12 | LABEL N | 随后有 N 个字节的标识数据 |
| 13 | KEY N | 随后有 N 个字节的键数据 |
| 14 | ASCII N | 随后有 N 个(8 位)字节的 ASCII 数据 |
| 15 | BLOCK N | 随后有 N 个字节的数据 |
我已经提到过对 SIZE 的要求。在任何含有块标志(ASCII 除外)的消息中缺少 SIZE 标志,都是确定的错误。EOM 部分地是另一种查错手段,部分地是绕过填充难题的手段。用户程序在输入时绝不应看到 EOM;用户可以写出一个 EOM 来强制发送。EOM 界定消息中有用信息的结尾,并重新给出消息中的总位数——从标记之后的第一个位开始,到 EOM 计数字段的最后一位结束——以检查可能的信息丢失。这是针对 IMP-HOST 电气接口以及 HOST 软泥件(mushyware)中错误的检查。除非已经出现了 ESC,否则 EOM 必须出现在每条消息的末尾。
ESC 意在充当一个(但愿)用不到的逃生舱口,供那些希望在任何链路上都不使用超过四位 USER-USER 协议的设施和/或应用不去使用。例如,可能有人希望把链路当作比特流来使用,甚至忽略消息边界。如果无政府主义者们能够达成本地约定,那就祝他们好运!
NUL 与 IGNORE 意在充当填空物,以防把随后数据块的第一个位安排在方便的地址边界上会有所帮助。(一个特别热心的 HOST 中断例程在接收消息时,甚至可能把 NUL 与 IGNORE 的组合粘贴到标记位之上——在这种情况下,应当把它们的位数一并传给 GET 例程,以修正 EOM 位数校验。)分隔操作引入了逻辑记录、组与文件这些概念。具体地说,并不要求一条记录必须完整地包含在一个消息之内,也不要求一个消息中只包含单独一条记录!此外,并不要求在一次连接期间只传送一个文件。例如,用户可能希望利用一条链路传送一组例程,然后拿这条链路去做别的事情。
于是,按照本地约定,单个例程可以由若干条记录组成并构成一个组,整个集合可以构成一个文件,而在收到 FS 标志之后链路可以保持连接。
对各种块标志的解释同样可以由本地约定决定。意在承载纯数据的两个标志是 ASCII 与 BLOCK;它们之间的差别(就协议而言)仅仅在于:对 ASCII 来说字节大小是隐含的(8 位),对 BLOCK 来说则是显式的(由最近一个在先的 SIZE 标志的计数字段给出)。然而,除此之外,跟在 ASCII 之后的块的语义内容受现行 ASCII 标准的约束;EBCDIC 信息不得在 ASCII 块中传送!!
CONTROL 与 STATUS 意在供用户进程之间交流控制信息,其附带数据块的解释由本地约定决定。一般地说,CONTROL 的意思是“试着做下面这件事”,STATUS 的意思是“不过我感觉是这样,大夫。”一个 CONTROL 标志会促使对方迟早返回一个 STATUS 标志,或者永远不返回。LABEL 意在用于在文件或组的层级上标识随后的数据单元。同样,具体解释属于本地约定的范围。KEY 意在模拟地址或键的概念——这是记录、数据项乃至物理存储块的层级。对于熟悉 PDP-10 系统和/或 OS/360 的人,下面提供一些类比以供参考:
USER-USER protocol OS/360 PDP-10
__________________ ______ ______
CONTROL OPEN OPEN
CLOSE CLOSE
LABEL DSCB File retrieval information
KEY KEY USETI/USETO argument
CONTROL READ IN/INPUT
WRITE OUT/OUTPUT
ALLOCATE ? ENTER
OPEN ? LOOKUP
STATUS ? GETSTS
上面的“?”记号表示缺少非常直接的对应物。值得注意的是,在任何体现了记录这一概念的 USER-USER 协议实现中,OS/360 的 GET 与 PUT 都有直接的对应物;我们对本协议的实现将为所有涉及磁盘与磁带存储以及 IMP 通信的 PDP-10 输入/输出引入这一概念。
如果我懂 MULTICS 的术语,我就能更精确地扩充上面这组类比。尽管我的术语取自那些具有显式输入/输出命令的系统,我仍想强调,这一套设定意在一般性地处理控制通信与数据通信;MULTICS 是一个(从用户角度看)外部存储与内部存储之间的经典区分被模糊掉的系统,我希望这种区分在 USER-USER 协议中也被模糊掉。我提出 SYS 时只有一点点忐忑。一般的想法是,人应当能够直接与一个外来的 HOST 通信,而不是经由一个作为中介的外来用户进程。SYS 类似于一个 UUO 或 SVC,但供外来的 HOST 消费,而不是供我自己的 HOST 消费。从 HOST 的角度看,实现上的问题在于建立一个与任何本地用户进程都无关的进程上下文记录。然而,这与我们当前的 LOGON 难题密切相关。例如,在 PDP-10 上,用户或多或少是与本地电传打字机线路联系在一起的,而任何链路都不是这些线路之一!因此,为了让一个外来用户登录,就需要一些障眼法。OS/360 以自己的方式同样(实际上更)乖僻。
把一个外来进程登录到我的本地系统,并不是(MULTICS 可能除外)简单地让一个专门(!!)的用户作业在场并负责完成此事。当且仅当别的方式有可能时,HOST 必须提供一条系统指令(UUO 或 SVC 或随便什么),给出所需的信息,从而建立一个在一切意义上都独立于发出请求的那个进程的进程。否则,对任何系统来说都合情合理的自我保护机制,将使我们所有人变得比我们所希望的更加互相依赖。要做到这一点,每个系统中都必须存在一条做正确之事的 UUO/SVC(ATTACH,但是把我忘掉)。如果确实如此,那么经由 Network 的 LOGON 过程就等同于由 Network 中另一个节点发出一个外来的 UUO/SVC。我看不到有什么合理的办法绕开这一点。如果是这样,那么 SYS N 就是用来传送所需数据的那种标志。如果确实如此,那么让 SYS 传送一条对用户程序-操作系统接口一级的任何 OS 指令的请求,就只是顺理成章的事了!
实现上的实际问题又是另一回事!就 PDP-10 而言,我相当清楚地看到如何把一个 SYS 变成一条执行监视器命令或 UUO 的 LOGON 请求(但愿这两者是一回事),视具体情况而定。不幸的是,OS/360 更为精细。MULTICS 也许能行。话虽如此,我希望有一点是清楚的:我们想要做什么——这正是协议应当反映的——与在一个特定 HOST 系统的语境下如何去做,是完全不同的问题。就协议而言,我们想要做的事一般与我们正在打交道的系统相当无关,我们不应仅仅因为不确定如何把它们转化为具体的实现实践,就不把一般的概念引入协议之中。