简单的 NCP 协议( 二 )


ACDL
参数的取值为前面提到的RFDL中的和远程NCP的消息缓冲区数这两个中的较小值 。假如套接口号不能被匹配,那么就返回一个ACDL的错误消息,其中值为零 。需要注重的是,RFDL机制与RFC机制类似,只是在前者中,队列大小为1并且是否同意建立连接完全由NCP来决定 。
两个侦听方法的变种对应着两种通道操作模式 。单参数的变种将用于“与任何在线主机通讯”的程序,典型的如LOGIN进程 。至于和谁通信则由用户进程决定 。双参数变种则用于用户知道自己将和谁通信并且不希望被其它主机的随机RFDL所打断的情况 。假如套接口名字空间分成几个部分,那么只有从特定的进程中才能获取匹配的RFDL 。
远程主机在发送ACDL前分配用于连接的消息缓冲区,而本地主机则在收到ACDL时分配缓冲区 。每端的缓冲区数与ACDL中的参数相等 。所有的远程缓冲区的状态是“空”,所有的本地缓冲区的状态是“布满着空箱子” 。消息缓冲区分配完毕后,本地的用户进程将会被告知,然后它就能开始发送消息 。
NCP所涉及到的用户进程和新建双工链路间的接口类型由相应主机所决定 。一个简单而完整的接口能提供两个NCP调用 。GETMESSAGE将会从链路中返回下一个消息,消息包括标记,文本和填充字节 。PUTMESSAGE将会取一个只包括标记和文本的消息,并且将其缓冲起来预备发送 。假如有明显的逻辑错误将会报告 。
我们建议将消息对齐的责任留给用户 。在大部分机器上这是一个简单但耗时的操作 。假如在NCP中实现,也不能保证用户不用再重新对其调整 。光靠经验是不大可能知道文本部分究竟应该是向左,或向右来调整而使得字对齐,又或者与最后一条消息末对齐,又或者用非凡的方式来将消息分片 。
在本协议中消息边界将用于提供存储分配信息 。假如用户没用到该信息,那么可以忽略它,用户接口就能看作是一个位流 。虽然这种策略受到纯粹主义者的欢迎,然则在试图同步链路两端的时候,这种策略就会使事情变得复杂 。
通过从链路中删除空箱子并且回收分配给这些空箱子的缓冲,就可以删除一条链路 。只有那些含有箱子的缓冲才能被回收,空的缓冲必须被保留来接收随时而来的消息 。当所有的箱子都被删除后,缓冲也不再存在了,并且套接口号可以被忽略 。当删除空箱子的时候,一个精简的消息将会发送给外部NCP,让它减少分配给缓冲区的存储量 。这个消息的格式如下:
DEC
然后外部NCP会被要求发送一个应答来确定删除操作的正确执行或者告知错误的发生 。错误可能是“没有这个链路”或者“删除的缓冲区数不可能” 。
有两个系统调用可供用户进程选择来关闭一条链路 。NOMOREOUTPUT会声称本地用户进程不会再发送消息 。相应的拥有空箱子的链路的所有本地缓冲被NCP回收 。DEC消息将会被发送给外部NCP 。在箱子为空的情况下,通过GETMESSAGE调用也把它们的缓冲回收 。另外一个系统调用是KILLMESSAG 。这个调用可用来代替PUTMESSAGE. 。KILLMESSAG将回收空箱子和发送一个DEC控制消息,而不是用将要发送的消息来填充空箱子 。
在用户进程僵死或者其它不能关闭链路的情况下,必须采取应急措施 。在这些情况下,我们定义了ABEND控制消息:
ABEND
在发送了一个ABEND后,发送这个消息的NCP就开始关闭链路 。所有包括输入信息的缓冲将会被关闭 。针对这些缓冲以及以前的空缓冲,将会给外部NCP发送一个DEC消息 。假如链路中消息到达了,这些消息被销毁并且会发送一个DEC 。从该链路中收到的任何ABEND消息会被忽略 。

推荐阅读