跳到主要内容

III. 环境

我们假定, 典型的主机会有一个分时操作系统, CPU 由各进程共享。

进程​

我们设想每个进程都带有一个用户号标签。可能有多个进程具有相同的用户号, 如果是这样, 它们在使用网络方面应当相互协作。

我们设想每个进程都包含一组为该进程所独有的端口。这些端口用于进程的输入或输出, 数据来自或去往文件、设备或其他进程。

我们还设想每个进程都有一个事件通道, 通过它可以接收非常短的消息 (几个比特)。我们将用这一机制来通知进程, 在它之外发生了某个动作。

为了参与网络活动, 进程把一个本地 socket 连接到它的某个端口上。socket 由用户号、主机和 AEN 来标识, 如果一个 socket 与一个进程的用户号相同且位于同一台主机中, 那么该 socket 对该进程而言就是本地的。进程在引用本地 socket 时只需指定 AEN。

每个端口都有一个状态, 该状态会被系统调用以及进程外部的并发事件修改。每当某个端口的状态发生变化时, 就会通过进程的事件通道向它发送一个事件, 指明是哪个端口的状态发生了变化。随后进程可以查看该端口的状态。

下文的描述性材料用到了这些假设。不过, 这些假设并非网络协议所强加的, 第 IV 节所建议的实现也绝无约束力。

我们希望讲得非常清楚: 提供这些材料只是为了提示实现中可能会遇到哪些困难, 而不是要强加任何特定的规范。

例如, 我们把到达未连接的本地 socket 的 <RFC> 视为合法的并将其排队。如果需要, NCP 也可以像 Meyer 建议的那样拒绝它们, 或者把它们保留一段时间, 如果不能很快得到满足再予以拒绝。所提出的协议支持所有这些选择。

另一个本地选择就是前面提到的把多个端口连接到一个 socket 上。我们展示的是一一对应, 但这一点可以不予理会。同样, 这些系统调用也仅仅是示意性的。

系统调用​

下面是用户进程可能执行的一些典型系统调用。我们列出它们只是为了完整起见; 每个站点无疑都会实现任何方便的等价集合。

我们使用如下记法

        Syscall ( arg , arg ...; val ... )
1 2 1

其中

  1. Syscall 是系统调用

  2. arg₁ 等是随调用提供的参数, 而

  3. val₁ 等是系统调用返回的值。

Init (P,AEN,FS,Bsiz;C)​

  1. P: 指定进程的一个端口。

  2. AEN: 指定一个本地 socket。本进程的用户号和本主机的主机号是隐含的。

  3. FS: 指定任意主机中具有任意用户号、任意 AEN 的一个 socket。

  4. Bsiz: 指定用户想要用于缓冲消息的存储量, 以比特为单位。

  5. C: 返回的条件码。

Init 尝试把由 AEN 指定的本地 socket 连接到端口 P 上, 并发起与 socket FS 的连接。C 可能的返回值有

  1. C = ok: 该 Init 合法, 正在联系 socket FS。当连接建立或者 FS 拒绝时, 进程将收到一个事件。

  2. C = busy: 该本地 socket 正被本进程或具有相同用户号的其他某个进程的一个端口使用。未采取任何动作。

  3. C = homosex: AEN 和 FS 同为发送 socket 或同为接收 socket。

  4. C = nohost: FS 中指定的主机未知。

  5. C = bufbig: Bsiz 过大。

Listen (P,AEN,Bsize;C)​

  1. P: 指定进程的一个端口。

  2. AEN: 指定一个本地 socket。

  3. Bsiz: 指定缓冲区大小。

  4. C: 返回的合法性代码。

C 的代码有

C = ok

C = busy

C = bufbig

由 AEN 指定的本地 socket 被连接到 P 上。如果有等待中的呼叫, 就处理它; 否则不采取任何动作。当有呼叫到来时, 将建立一条连接, 并通过一个事件通知进程。

Close (P)​

P 指定进程的一个端口。

所有活动都被停止, 该端口变为空闲, 可作他用。

Transmit (P,M,L1;L2,C)​

  1. P: 指定具有一条打开连接的端口。

  2. M: 要传输的文本。

  3. L1: 指定文本的长度。

  4. L2: 实际传输的长度。

  5. C: 错误码。

在端口两侧的进程之间进行传输。

C 的代码有

C = ok

或

  1. C = not open: 当前没有打开的连接, 且其他方面未被禁止

Status (P;C)​

端口 P 的状态以 C 的形式返回。