跳到主要内容

总体说明

在我们看来, 每台主机都有一组四个程序, 用于让用户的电传打字机与外部监控程序通信。这些程序的具体实现与各站点的环境高度相关。因此, 所有说明都旨在描述功能特性, 而非设计。

这四个程序分为两对“公/母”。用户在本站点使用发送记录器, 与相应外部站点的接收记录器通信, 从而在用户的电传打字机与外部机器的监控程序之间建立一条全双工链路。这使他处于相当于已在对方机器上预先登录的状态。链路建立之后, 两个记录器就退出舞台, 用户转而与本地机器中的发送方对话, 后者的主要功能是接收用户电传打字机的输入, 并沿记录器所建立的链路发送给外部主机中的接收方, 由接收方转交给其监控程序(使其看起来像是来自本地电传打字机的输入)。外部监控程序的应答交给接收方, 由接收方沿链路回传给发送方, 再由发送方输出到用户的电传打字机上。每台机器中的发送方和接收方要么存在多个副本(每个网络用户一个), 要么只有一个副本能处理所有网络用户。不过, 记录器只需能同时处理一个用户, 因为它们的任务很快完成, 从而可以腾出来满足其他请求。但应当有某种排队机制来处理无法立即满足的请求。较不理想的替代方案是, 当记录器忙时向试图使用它的用户返回一条忙消息。(当然, 这并不排除某个站点拥有可重入记录器, 或拥有多个记录器副本的可能性。)

接收记录器在每台机器中都应当是用户零, 并始终监听套接字零。(同样的事情也可以通过让 NCP 截获所有发往用户零、套接字零的消息并把它们送给接收记录器来实现; 但让记录器本身就是用户零, 由 NCP 像处理其他所有人的消息一样处理它的消息, 更简单也更干净。)

调用发送记录器时, 它从空闲套接字池中取出一对未使用的套接字(2N 和 2N+1), 并从 2N+1 向目标外部主机中的用户 0、套接字 0 发起 CONNECT。这会激活接收记录器, 如果有可用的位置留给外部电传打字机, 它就接受连接。随后它立即关闭这条连接, 以便来自其他来源的链路能够发起。反之, 如果没有位置留给该外部电传打字机(或者由于其他原因, 接收记录器不愿连接), 则对套接字零的连接尝试被拒绝。这会通知发送记录器无法登录外部主机, 并由它把这一情况通知用户。然而, 并不能保证这次关闭确实是由外部记录器发出的。例如, 如果该套接字的待处理呼叫队列过载, 它也可能是由 NCP 发出的。

如果对套接字零的链路已被接受(这表明接收记录器能够满足该请求), 那么在关闭该链路之后, 接收记录器从自己的池中挑出一对可用套接字(2M 和 2M+1), 并从 2M+1 连接到 2N。(当它的监听被来自 2N+1 的链路应答时, 它就知道了 2N 的身份。)与此同时, 发送记录器一直在监听套接字 2N, 此时接受该链路, 并从 2N+1 向 2M 发起 CONNECT。接收记录器一直在监听这个套接字, 并接受这次连接尝试。

此时, 两个记录器之间已有一条全双工连接。它们随后启动发送方和接收方, 由这两者处理用户与外部监控程序之间的所有其他通信。(发送方和接收方可以是记录器的一部分, 也可以由记录器调用, 等等。)

当用户结束并返回自己的监控程序时, 由发送方负责关闭链路。在接收端, 非常希望 NCP 能把这一情况通知接收方, 这样它就可以让用户注销(如果用户自己没有这样做的话), 并释放用户此前占用的任何资源。

上文场景所述协议的一个更正式的大纲如下:

  1. 稳定状态: 外部主机上的接收记录器监听用户 0、套接字 0。

  2. 本地用户调用发送记录器。

  3. 发送记录器调用 CONNECT (port, 2N+1, <foreign host#,0,0>)。

  4. 发送记录器调用 LISTEN (port, <local host#, user#, 2N>)。

  5. 外部记录器的 LISTEN 得到应答, 并被告知本地用户号、主机号和 #2N+1。

  6. 外部记录器寻找可用套接字(2M 和 2M+1)。如果存在并且它能够建立连接, 它就接受, 然后立即关闭该链路。

  7. 外部记录器调用 CONNECT (port, 2M+1, <local host#, user#, 2N>)。

  8. 外部记录器调用 LISTEN (port, <local host#, user#, 2M>)。

  9. 发送记录器已监听 2N 并接受链路, 然后调用 CONNECT (port, 2N+1, <foreign host#, user#,2M>)。

  10. 接收记录器正在监听 2M, 接受链路。

  11. 记录器启动相应的处理程序。

  12. 当用户结束时, 发送方关闭两条链路。

这种建立全双工连接的基本方法应当在全网统一。各站点如何处理发送方、接收方和两个记录器的实现, 对网络而言无关紧要, 并且高度依赖具体机器。(甚至需要发送方和接收方这一点也依赖具体机器, 因为网络中的某些成员也许能以其他方式完成它们的功能。)然而, 关于发送方与接收方(或它们的等价物)之间的通信, 必须确立某些约定。