初始连接协议
我们就具体的初始连接协议(IPC)提出两点。 第一,NEW/RFC #66 中所述 IPC——它的通用性,以及对该 ICP 的复述。 第二,一项变体 ICP 的提案,它基本上沿用与 NWG/RFC #66 相同的逻辑。
I. NWG/RFC #66
该 IPC 中唯一的技术性错误在于,如图所示,服务器与用户都在连接建立之前发送全部消息,这与 Network Document No. 1 不一致。 这一点很容易补救,如下文复述所示。
就通用性而言,任何被采纳为标准 ICP 的协议都应适用于比「进程调用 Logger」更多的情况。 也就是说,某些直接挂接到用户进程、不依赖 Logger 动作的网络服务进程,也许可以使用标准 ICP。因此,如下所示,服务器套接字的进程名字段应当是一个参数,其值为零则是面向 Logger 的特殊情形。
NWG/RFC #66 的复述(在适当处沿用原文措辞)
- 为发起接触,使用进程附加一个接收套接字(US),并请求连接到服务 HOST 中的进程 SERV 套接字 #1。(对 Logger 的 ICP 而言 SERV = 0。) 于是使用方 NCP 发送:
1 4 3 1 1
+-----+---------------------+---------------+-----+-----+
| RTS | US | SERV | 1 | P |
+-----+---------------------+---------------+-----+-----+
经由链路 1,其中 P 是接收链路。
- 服务进程(SERV)可能决定拒绝该调用,此时它会关闭连接。 如果它接受调用,服务进程就完成连接(通过 INIT 系统调用,因而产生 STR)。
1 3 1 4
+-----+----------------+-----+--------------------+
| STR | SERV | 1 | US |
+-----+----------------+-----+--------------------+
- 连接完成后,用户进程为该连接分配名义上的一点空间,于是 NCP 发送:
1 1 4
+-----+-----+--------------------+
| ALL | P | SPACE |
+-----+-----+--------------------+
其中 SPACE 是所分配的数量。
-
随后服务进程选择它希望分配给该用户的套接字对。 它恰好经由该连接发送一个偶数 32 位数字。 这个偶数 32 位数字(SS)是服务 HOST 中的接收套接字。 该套接字及其编号更高的下一个套接字预留给使用进程。
-
然后它关闭连接。 服务方 NCP 发送(步骤 4):
4
+---------------------+
| SS |
+---------------------+
在链路 P 上,以及(步骤 5):
1 3 1 4
+-----+----------------+-----+--------------------+
| CLS | SERV | 1 | US |
+-----+----------------+-----+--------------------+
在控制链路上(由使用方 NCP 回送)。
- 既然服务器与用户双方都已知道该双工连接的远端套接字对,就可以交换多个 <STR, RTS> 了。
服务器发送给用户
1 4 4
+-----+--------------------+--------------------+
| STR | SS + 1 | US |
+-----+--------------------+--------------------+---+
| RTS | SS | SS + 1 | Q |
+-----+--------------------+--------------------+---+
其中 Q 是服务器的接收链路。
用户发送给服务器
1 4 4
+-----+--------------------+--------------------+
| STR | US + 1 | SS |
+-----+--------------------+--------------------+---+
| RTS | US | SS + 1 | R |
+-----+--------------------+--------------------+---+
其中 R 是用户的接收链路。
此后可以发送 ALLocate,传输随之开始。
II. NWG/RFC #66 的一个变体
这一变体减少了网络消息,并消除了信息传输的重复。
上面的步骤 3 和 4 被删除。 不再直接通知用户进程它将被分配到服务器的哪一个套接字。 不过,用户进程将在上面的步骤 5 之后,在套接字 US 和 US + 1 上监听来自 SERV 的调用。 它可以拒绝任何虚假的调用。 在接受来自 SERV 的调用时,连接即告建立。
下面的示例序列说明了这一 ICP。 (记法同上)。
- 用户 --> 服务器
1 4 3 1 1
+-----+--------------------+----------------+-----+-----+
| RTS | US | SERV | 1 | P |
+-----+--------------------+----------------+-----+-----+
- 服务器 --> 用户
如果接受:
1 3 1 4
+-----+----------------+-----+---------------------+
| STR | SERV | 1 | US |
+-----+----------------+-----+---------------------+
| CLS | SERV | 1 | US |
+-----+----------------+-----+---------------------+
如果拒绝:
1 3 1 4
+-----+----------------+-----+---------------------+
| CLS | SERV | 1 | US |
+-----+----------------+-----+---------------------+
-
如果接受,用户就在 US 和 US + 1 上监听。
-
服务器 --> 用户
1 4 4
+-----+--------------------+---------------------+
| STR | SS + 1 | US |
+-----+--------------------+---------------------+---+
| RTS | SS | US + 1 | Q |
+-----+--------------------+---------------------+---+
- 用户接受这些调用,因此:
用户 --> 发送方
1 4 4
+-----+---------------------+--------------------+
| STR | US + 1 | SS + 1 |
+-----+---------------------+--------------------+---+
| RTS | US + 1 | SS | R |
+-----+---------------------+--------------------+---+
连接随之建立。
这使网络消息数量减少两条,并且只经由 RTS 和 STR 传递一次有关服务器套接字的信息。