> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-si-bu-fen-jin-cheng-jian-tong-xin/12.11.-xiao-jie.md).

# 12.11 小结

本节把前三章的许多材料串成一体，办法是描述套接字层和网络层在正常使用中的运作。

套接字的一生有三个阶段：初建——创建套接字并与某个通信域关联；存活——数据经它流往一个或多个其他套接字；终结——不再需要时，经过有序的关闭过程释放资源。

**创建通信信道**

套接字由用户用 `socket` 系统调用创建，内部经 `socreate()` 例程。创建套接字时，用户须给出通信域和套接字类型，还可以请求域内的具体通信协议。套接字例程先从引导时为每个配置域初始化的全局列表中定位通信域的 `domain` 结构；域结构中找到构成该域协议族的协议表；然后扫描这张协议开关表项的表，为所创建套接字的类型（或指定的具体协议）找合适的协议。套接字例程靠检查 `pr_type` 字段（含可能的套接字类型，如 SOCK\_STREAM）和 `pr_protocol` 字段（含协议的协议号，通常是著名值）完成搜索。找到合适的协议，对它协议开关表项的引用就记入套接字的 `so_proto` 字段，此后一切网络服务请求都经结构中标识的相应过程进行。

定位到协议的句柄后，`socreate()` 分配一个 mbuf、以套接字的初始状态创建套接字数据结构。为完成创建，`socreate()` 向协议的用户请求例程发 PRU\_ATTACH 请求，让协议把自己 **附接** 到新套接字上。

接着可以把地址绑定到套接字。地址的绑定内部由 `sobind()` 完成，它向套接字的支撑协议发 PRU\_BIND 请求。Internet 和 XNS 域各有一个管理自己地址空间的例程。UNIX 域的地址是文件系统名字空间中的名字，名字请求因此要经文件系统的名字查找例程 `namei()`。

套接字要准备接受连接，套接字层必须以 PRU\_LISTEN 请求告知协议。这一请求对 UDP 和 IDP 等无连接协议显然无意义；对 TCP 和 SPP 等面向连接的协议，listen 请求则引起协议状态转换。状态转换前，协议核实套接字已绑定地址；没有，协议模块替它选一个。

UNIX 域中 listen 请求不引起状态变化，只检查套接字有名字；但与其他协议不同，UNIX 域不替套接字选名字。

`soconnect()` 被调来建立连接，向协议发 PRU\_CONNECT 请求。无连接协议把地址记为默认地址，供套接字上发送数据时使用（即进程做 `write` 或 `send` 而不是 `sendto`）；设置地址无须任何对端通信，协议模块立即返回。

基于连接的协议则验证对端地址，为未绑定的套接字指派本地地址。套接字不立即进入 **已连接** 状态，而是经 `soisconnecting()` 标记为 **连接中**；协议随即发送连接请求消息与对端握手。这种连接请求完成时——通常在协议输入例程收到消息之际——套接字的状态经调用 `soisconnected()` 改变。

在用户看来所有连接请求都是同步的：`connect` 系统调用调用 `soconnect()` 发起连接，然后在套接字层把调用进程入睡（若连接请求尚未完成）。或者，套接字已经 `fcntl` 成非阻塞时，连接一经成功发起 `connect` 就返回 EINPROGRESS 错误；调用者可以用 `select` 测试能否写套接字来检验连接的完成。

基于连接的通信中，进程必须在监听套接字上调用 `accept` 接受入局连接请求，后者转而调用 `soaccept()`，从套接字接收队列返回下一个已完成的连接。

**收发数据**

套接字一经创建，数据就可以开始流经它。一条典型的 TCP/IP 连接见图 12.10。`sosend()` 例程负责把数据从发送进程的地址空间复制进 mbuf，然后以一次或多次对协议 PRU\_SEND 请求的调用把数据呈交网络层。网络可以选择立即发送数据或等更好的时机；协议若推迟、或必须保留数据副本以备重传，可以把数据存在套接字的发送缓冲。最终，数据经 TCP 和 IP 向下传给适当的接口驱动程序，成为一个或多个分组；每层都加上相应的头部。每个分组经网络发往目的机器。

![图 12.10 TCP/IP 连接经以太网的数据流（ETHER 为以太网头；PIP 为伪 IP 头；IP 为 IP 头；TCP 为 TCP 头）](https://1991889543-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FilVST9xTgD47M0g8ham7%2Fuploads%2Fgit-blob-2840c774c088cc50327e3522073dfabe7163660e%2Ffig-12-10-figure-12-10-data.png?alt=media)

目的机器收到时，接口驱动的接收中断处理程序校验并剥掉自己的头部，把分组放上适当的网络协议输入队列。稍后，网络级输入处理模块（如 IP 或 IDP）被软件中断唤起；它运行的中断优先级低于硬件网络接口中断。本例中，输入队列上的分组先由 IP 再由 TCP 处理，各自校验并剥掉自己的头部。按序收到的话，数据随即放到适当套接字的输入队列上，等 `read` 请求到来时由 `soreceive()` 复制出去。

**终止数据传输和/或接收**

`soshutdown()` 例程停住套接字处的数据流。关闭套接字的读取很简单：冲掉接收队列并标记套接字不能再收数据——调用 `sorflush()`，它转而调用 `socantrcvmore()` 改变套接字状态，然后释放接收队列关联的资源。关闭套接字的写入则要经 PRU\_SHUTDOWN 请求通知协议。可靠连接的发送队列中若仍有数据，必须排空后连接才能完成关闭。协议若支持 **半打开** 连接（即允许单向数据流的连接），套接字可以继续使用；否则协议可以开始断开序列。套接字两个方向都关闭后，协议开始断开序列；断开完成时，先释放网络关联的资源，再释放套接字关联的资源。

## 习题

12.1 TCP 是传输层、网络层还是链路层协议？

12.2 IP 如何识别应处理入局消息的下一个更高层协议？这一分派在施乐 NS 体系结构中有何不同？

12.3 C 类 Internet 网络上能有多少台主机？C 类网络能用子网编址吗？

12.4 什么是广播消息？DARPA Internet 中如何识别广播消息？

12.5 TCP 和 UDP 的协议控制块为什么放在不同的链表上？

12.6 检查外出分组的目的地址是否广播地址的为什么是 IP 输出例程，而不是套接字层的发送例程（`sosend()`）？

12.7 4.3BSD 为什么不转发广播消息？

12.8 TCP 头总是封装在含 TCP 消息长度的 IP 分组中，为什么还要有头部长度字段？

12.9 TCP 限制数据发送速率的流控机制是什么？

12.10 TCP 如何识别发自主机、指向先前存在但已关闭的连接（比如机器重启之后）的消息？

12.11 什么时候连接的 TCP 接收窗口不等于关联套接字接收缓冲的可用空间量？此时两值为何不等？

12.12 什么是保活消息？TCP 用它做什么？保活消息为什么实现在内核而不是实现在每个想要这一设施的应用里？

12.13 计算平滑往返时间为什么重要，而不是比如简单平均算出的往返时间？

12.14 TCP 为什么对收到的数据延迟确认？TCP 延迟确认的最长时间是多少？

12.15 解释糊涂窗口综合症是什么，举一个避免它对良好协议性能很重要的例子。4.3BSD TCP 如何避免这一问题？

12.16 **小分组避免** 指什么？为什么小分组避免对呈现单向数据流、需要低延迟才有好的交互性能的客户（如 X Window System）不利？

\*12.17 **定向广播** 是要在离发送方一跳或多跳之外的网络上广播的消息。描述在 Internet 域中支持定向广播消息的方案。

\*12.18 TCP 连接的初始序号为什么随机选择，而不是比如恒设为零？

\*12.19 TCP 协议中 SYN 和 FIN 标志为什么占据序号空间？

\*12.20 描绘连接建立期间典型的 TCP 分组交换。假设主动客户向被动服务器发起连接。被动服务器若同时试图向客户发起连接，这一场景会有何变化？

\*12.21 勾画服务器进程接受连接后未收任何数据即立即关闭时的 TCP 状态转换。4.3BSD 若支持服务器在系统完成连接前拒绝连接请求的机制，这一场景会有何不同？

\*12.22 4BSD TCP 一度用严格指数退避策略做传输。解释这一非自适应算法如何损害带宽高但 **丢包多** 的网络（如某些使用卫星连接的网络）上的性能。

\*12.23 UDP 为什么把入局消息完全指定的目的地址与本地和远程目的地址不完整的套接字相匹配？

\*12.24 发送方为什么可能在 IP 分组头设置 **不可分片** 标志？

\*12.25 **报文段最长生存期**（MSL）是消息在网络中存在的最长时间，即消息在某种硬件介质上传输或排队在网关中的最长时间。TCP 做什么保证 TCP 消息有有限的 MSL？IP 做什么强制有限的 MSL \[Fletcher & Watson, 1978]？

\*\*12.26 描述一个为网际环境中消息的报文段最长生存期计算上界的协议。TCP 怎样用消息的 MSL 上界（见习题 12.25）把关闭 TCP 连接的开销降到最小？

## 参考文献

BBN, 1978. BBN, “Specification for the Interconnection of Host and IMP,” Technical Report 1822, Bolt, Beranek, and Newman, Cambridge, MA (May 1978).

CCITT, 1980. CCITT, “Recommendation X.25: Interface between Data Terminal Equipment (DTE) and Data Circuit-Terminating Equipment (DCE) for Terminals Operating in the Packet Mode on Public Data Networks,” in *Public Data Networks, Orange Book, vol. VIII.2* (1980).

Carr et al., 1970. S. Carr, S. Crocker, & V. Cerf, “HOST–HOST Communication Protocol in the ARPA Network,” *Proceedings of the AFIPS Spring Joint Computer Conference*, pp. 589–597 (1970).

Cerf, 1978. V. Cerf, “The Catenet Model for Internetworking,” Technical Report IEN 48, SRI Network Information Center, Menlo Park, CA (July 1978).

Cerf & Kahn, 1974. V. G. Cerf & R. E. Kahn, “A Protocol for Packet Network Intercommunication,” *IEEE Transactions on Communications* **22**(5), pp. 637–648 (May 1974).

Clark, 1982. D. D. Clark, “Window and Acknowledgment Strategy in TCP,” RFC 813, SRI Network Information Center, Menlo Park, CA (July 1982).

DARPA, 1983. DARPA, “A History of the ARPANET: The First Decade,” Technical Report, Bolt, Beranek, and Newman, Cambridge, MA (April, 1983).

Fletcher & Watson, 1978. J. Fletcher & R. Watson, “Mechanisms for a Reliable Timer-Based Protocol,” pp. 271–290 in *Computer Networks* 2, North-Holland, Amsterdam, The Netherlands (1978).

Heart et al., 1970. F. E. Heart, R. E. Kahn, S. Ornstein, W. Crowther, & D. Walden, “The Interface Message Processor for the ARPA Computer Network,” *Proceedings of the AFIPS Spring Joint Computer Conference*, pp. 551–567 (1970).

ISO, 1984. ISO, “Open Systems Interconnection—Basic Reference Model,” ISO 7498, International Organization for Standardization (1984). Available from: American National Standards Institute, 1430 Broadway, New York, NY 10018.

Jacobson, 1988. V. Jacobson, “Congestion Avoidance and Control,” *Proceedings of the ACM SIGCOMM Conference*, pp. 314–329 (August 1988).

McQuillan & Walden, 1977. J. M. McQuillan & D. C. Walden, “The ARPA Network Design Decisions,” *Computer Networks* **1**(5), pp. 243–289 (1977).

McQuillan et al., 1980. J. M. McQuillan, I. Richer, & E. Rosen, “The New Routing Algorithm for the ARPANET,” *IEEE Transactions on Communications* **28**(5), pp. 711–719 (May 1980).

Mogul, 1984. J. Mogul, “Broadcasting Internet Datagrams,” RFC 919, SRI Network Information Center, Menlo Park, CA (October 1984).

Mogul & Postel, 1985. J. Mogul & J. Postel, “Internet Standard Subnetting Procedure,” RFC 919, SRI Network Information Center, Menlo Park, CA (August 1985).

Nagle, 1984. J. Nagle, “Congestion Control in IP/TCP Internetworks,” RFC 896, SRI Network Information Center, Menlo Park, CA (January 1984).

Padlipsky, 1985. M. A. Padlipsky, *The Elements of Networking Style*, Prentice-Hall, Englewood Cliffs, NJ (1985).

Postel, 1980. J. Postel, “User Datagram Protocol,” RFC 768, SRI Network Information Center, Menlo Park, CA (August 1980).

Postel, 1981a. J. Postel, “Internet Protocol,” RFC 791, SRI Network Information Center, Menlo Park, CA (September 1981).

Postel, 1981b. J. Postel, “Transmission Control Protocol,” RFC 793, SRI Network Information Center, Menlo Park, CA (September 1981).

Postel, 1981c. J. Postel, “Internet Control Message Protocol,” RFC 792, SRI Network Information Center, Menlo Park, CA (September 1981).

Postel et al., 1981. J. B. Postel, C. A. Sunshine, & D. Cohen, “The ARPA Internet Protocol,” *Computer Networks* **5**(4), pp. 261–271 (July 1981).

Scheifler & Gettys, 1986. R. W. Scheifler & J. Gettys, “The X Window System,” *ACM Transactions on Graphics* **5**(2), pp. 79–109 (April 1986).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-si-bu-fen-jin-cheng-jian-tong-xin/12.11.-xiao-jie.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
