2. Philosophy (哲学)
本章总结了TCP设计的哲学基础 (philosophical basis),阐述了TCP在互联网环境中的定位、设计原则和核心理念。
2.1. Elements of the Internetwork System (互联网系统的元素)
互联网环境由连接到网络的主机 (hosts) 组成,这些网络又通过网关 (gateways) 互连。这里假设网络可以是局域网 (local networks, 例如ETHERNET) 或大型网络 (large networks, 例如ARPANET),但无论如何都基于分组交换技术 (packet switching technology)。
核心概念
- 进程 (Processes): 产生和消费消息的活动代理 (active agents)
- 进程间通信系统: 网络、网关和主机中的各级协议支持进程端口 (process ports) 之间逻辑连接上的双向数据流
分组 (Packet) 一词在这里通用地表示主机与其网络之间的一次事务的数据。网络内部交换的数据块格式通常不是我们关心的问题。
术语定义
| 术语 | 定义 |
|---|---|
| 主机 (Host) | 连接到网络的计算机,从通信网络的角度来看,是分组的源和目的地 |
| 进程 (Process) | 主机计算机中的活动元素 (作为执行中的程序的相当常见的定义) |
| 端口 (Port) | 进程用于通信的逻辑端点,一个进程可能有多个端口 |
重要观点: 所有通信都被视为进程间通信 (inter-process communication)。即使终端、文件或其他I/O设备也被视为通过使用进程相互通信。
2.2. Model of Operation (操作模型)
数据传输流程
发送进程
↓ [调用TCP,传递数据缓冲区]
发送TCP
↓ [将数据打包成段]
互联网模块
↓ [封装成互联网数据报]
本地网络
↓ [嵌入本地网络分组]
... (通过分组交换机、网关) ...
↓
目标本地网络
↓ [解封装]
目标互联网模块
↓ [提取TCP段]
接收TCP
↓ [将数据放入用户缓冲区]
接收进程
详细说明
-
发送端:
- 进程调用TCP并传递数据缓冲区作为参数
- TCP将这些缓冲区中的数据打包成段 (segments)
- TCP调用互联网模块 (internet module),将每个段传输到目标TCP
-
接收端:
- 接收TCP将段中的数据放入接收用户的缓冲区
- 通知接收用户
-
控制信息:
- TCP在段中包含控制信息,用于确保可靠的有序数据传输
互联网通信模型
[TCP段] → [互联网数据报] → [本地网络分组] → ...网关转发... → [目标]
互联网模块 (Internet Module):
- 与每个TCP关联
- 提供到本地网络的接口
- 将TCP段封装在互联网数据报 (internet datagrams) 内
- 将这些数据报路由到目标互联网模块或中间网关
本地网络传输:
- 为了通过本地网络传输数据报,它被嵌入到本地网络分组 (local network packet) 中
- 分组交换机可能执行进一步的封装、分片 (fragmentation) 或其他操作以实现本地分组到目标互联网模块的交付
网关操作
在网络之间的网关处:
- 解封装: 互联网数据报从其本地分组中"解包"
- 检查: 确定互联网数据报接下来应该通过哪个网络
- 重新封装: 将互联网数据报"包装"在适合下一个网络的本地分组中
- 路由: 路由到下一个网关或最终目的地
分片机制 (Fragmentation):
- 如果传输需要,网关可以将互联网数据报分解为更小的互联网数据报片段 (fragments)
- 网关产生一组互联网数据报,每个携带一个片段
- 片段可能在后续网关处进一步分解为更小的片段
- 互联网数据报片段格式设计使目标互联网模块可以将片段重组为互联网数据报
服务类型 (Type of Service)
此操作模型掩盖了许多细节。一个重要特性是服务类型 (type of service),它提供信息给网关 (或互联网模块),以指导其选择遍历下一个网络时要使用的服务参数。
服务类型信息包括:
- 优先级 (Precedence): 数据报的优先级
- 安全信息 (Security Information): 允许在多级安全环境 (multilevel secure environments) 中运行的主机和网关适当地隔离数据报
2.3. The Host Environment (主机环境)
TCP被假定为操作系统中的一个模块。用户访问TCP的方式非常类似于他们访问文件系统的方式。
架构关系
用户进程
↓ [类似文件系统调用]
TCP模块
↓ [调用操作系统功能]
操作系统 (管理数据结构等)
↓
互联网数据报协议模块
↓
网络设备驱动程序
↓
物理网络
关键点:
- TCP可以调用其他操作系统功能,例如管理数据结构
- 到网络的实际接口假定由设备驱动程序模块 (device driver module) 控制
- TCP不直接调用网络设备驱动程序,而是调用互联网数据报协议模块,该模块反过来可能调用设备驱动程序
前端处理器实现
TCP的机制不排除在前端处理器 (front-end processor) 中实现TCP。然而,在这样的实现中,主机到前端协议 (host-to-front-end protocol) 必须提供功能来支持本文档中描述的TCP-用户接口类型。
2.4. Interfaces (接口)
TCP/用户接口
TCP/用户接口提供用户对TCP的调用,以执行以下操作:
| 调用 | 功能 |
|---|---|
| OPEN | 打开连接 |
| CLOSE | 关闭连接 |
| SEND | 发送数据 |
| RECEIVE | 接收数据 |
| STATUS | 获取连接状态 |
这些调用类似于用户程序对操作系统的其他调用,例如打开、读取和关闭文件的调用。
TCP/互联网接口
TCP/互联网接口提供调用以发送和接收寻址到互联网系统中任何主机的TCP模块的数据报。这些调用具有用于传递地址、服务类型、优先级、安全性和其他控制信息的参数。
2.5. Relation to Other Protocols (与其他协议的关系)
以下图表说明了TCP在协议层次结构中的位置:
应用层 (Application Level):
+------+ +-----+ +-----+ +-----+
|Telnet| | FTP | |Voice| ... | |
+------+ +-----+ +-----+ +-----+
| | | |
主机层 (Host Level):
+-----+ +-----+ +-----+
| TCP | | RTP | ... | |
+-----+ +-----+ +-----+
| | |
网关层 (Gateway Level):
+-------------------------------+
| Internet Protocol & ICMP |
+-------------------------------+
|
网络层 (Network Level):
+---------------------------+
| Local Network Protocol |
+---------------------------+
与高层协议的关系
TCP预期能够高效地支持高层协议。应该很容易将高层协议 (如ARPANET Telnet或AUTODIN II THP) 接口到TCP。
典型应用层协议:
- Telnet: 远程终端访问
- FTP: 文件传输
- Voice: 语音传输
- SMTP: 邮件传输 (虽然图中未明确列出)
2.6. Reliable Communication (可靠通信)
在TCP连接上发送的数据流在目的地可靠且按顺序交付 (reliably and in order)。
可靠性机制
序列号和确认 (Sequence Numbers and Acknowledgments)
传输通过使用序列号和确认变得可靠。从概念上讲,每个数据八位字节都分配了一个序列号。
- 段序列号 (Segment Sequence Number): 段中数据的第一个八位字节的序列号,与该段一起传输
- 确认号 (Acknowledgment Number): 段还携带确认号,这是反向传输中下一个预期数据八位字节的序列号
重传机制 (Retransmission Mechanism)
TCP发送包含数据的段
↓
将副本放在重传队列中
↓
启动计时器
↓
[等待确认]
├─→ [收到确认] → 从队列中删除段 ✓
└─→ [计时器超时] → 重传段 🔄
重要说明:
- TCP的确认不保证数据已交付给最终用户
- 确认仅表示接收TCP已承担这样做的责任
流量控制 (Flow Control)
为了控制TCP之间的数据流,采用了流量控制机制。
窗口机制 (Window Mechanism):
- 接收TCP向发送TCP报告一个"窗口" (window)
- 此窗口指定从确认号开始,接收TCP当前准备接收的八位字节数
- 发送方必须在窗口范围内发送数据
发送方: [已发送并确认] [已发送但未确认] [窗口内可发送] [不可发送]
↑
接收方窗口
2.7. Connection Establishment and Clearing (连接建立和清除)
套接字 (Sockets)
为了识别TCP可能处理的单独数据流,TCP提供了端口标识符 (port identifier)。由于端口标识符由每个TCP独立选择,它们可能不是唯一的。
套接字定义:
套接字 (Socket) = 互联网地址 + 端口标识符
套接字在所有连接在一起的网络中将是唯一的。
连接规范
- 连接 (Connection): 由两端的一对套接字完全指定
- 本地套接字: 可以参与到不同外部套接字的许多连接
- 全双工 (Full Duplex): 连接可用于双向传输数据
端口与进程
TCP可以自由地以它们选择的方式将端口与进程关联。然而,任何实现中都必须有几个基本概念:
- 知名套接字 (Well-Known Sockets): TCP仅通过某种方式将其与"适当的"进程关联
- 端口所有权: 进程可能"拥有"端口,进程只能在它们拥有的端口上发起连接
- 端口分配: 实现所有权的方法是本地问题 (例如,请求端口用户命令,或将端口名的高位与给定进程关联)
传输控制块 (TCB)
关于连接必须记住几件事。为了存储这些信息,我们假设有一个称为传输控制块 (Transmission Control Block, TCB) 的数据结构。
TCB内容:
- 本地和外部套接字
- 序列号
- 窗口大小
- 连接状态
- 其他控制信息
一种实现策略是让本地连接名成为指向此连接TCB的指针。
OPEN调用类型
被动OPEN (Passive OPEN)
被动OPEN请求意味着进程想要接受传入的连接请求,而不是尝试发起连接。
- 未指定外部套接字: 使用全零外部套接字表示未指定套接字
- 服务进程: 希望为未知其他进程提供服务的服务进程将发出具有未指定外部套接字的被动OPEN请求
- 知名套接字: 有助于此本地套接字已知与此服务相关联
知名套接字示例:
- Telnet-Server: 永久分配给特定套接字
- File Transfer: 保留套接字
- Remote Job Entry: 保留套接字
- Text Generator, Echoer, Sink: 用于测试目的
主动OPEN (Active OPEN)
主动OPEN请求用于发起连接。进程可以发出主动OPEN来连接到被动OPEN的服务。
同时主动OPEN
灵活性: 两个同时向对方发出主动OPEN的进程将被正确连接。这种灵活性对于支持分布式计算至关重要,在分布式计算中,组件相对于彼此异步地操作。
套接字匹配
匹配本地被动OPEN和外部主动OPEN中的套接字有两种主要情况:
- 完全指定: 本地被动OPEN已完全指定外部套接字。在这种情况下,匹配必须精确
- 未指定: 本地被动OPEN已保留外部套接字未指定。在这种情况下,只要本地套接字匹配,任何外部套接字都是可接受的
优先级: 如果有多个具有相同本地套接字的待处理被动OPEN (在TCB中记录),则外部主动OPEN将在选择具有未指定外部套接字的TCB之前匹配到具有外部主动OPEN中特定外部套接字的TCB。
三次握手 (Three-Way Handshake)
建立连接的程序利用同步 (SYN) 控制标志,并涉及三个消息的交换。这种交换被称为三次握手 [3]。
主动方 被动方
| |
| SYN (seq=x) |
|----------------->|
| |
| SYN-ACK (seq=y, ack=x+1)
|<-----------------|
| |
| ACK (ack=y+1) |
|----------------->|
| |
| ESTABLISHED |
连接建立过程:
- 连接由包含SYN的到达段和由用户OPEN命令创建的等待TCB条目的会合 (rendezvous) 发起
- 本地和外部套接字的匹配确定何时发起了连接
- 当双向的序列号都已同步时,连接变为"已建立" (established)
连接清除 (Connection Clearing)
连接的清除也涉及段的交换,在这种情况下携带FIN控制标志。
主动方 被动方
| |
| FIN (seq=x) |
|----------------->|
| |
| ACK (ack=x+1) |
|<-----------------|
| |
| FIN (seq=y) |
|<-----------------|
| |
| ACK (ack=y+1) |
|----------------->|
| |
| CLOSED |
2.8. Data Communication (数据通信)
在连接上流动的数据可以被认为是八位字节流 (stream of octets)。
PUSH功能
发送用户在每个SEND调用中通过设置PUSH标志来指示该调用 (以及任何先前的调用) 中的数据是否应立即推送到接收用户。
PUSH机制:
- 发送TCP: 允许从发送用户收集数据并以它自己方便的方式在段中发送该数据,直到发出push功能信号,然后它必须发送所有未发送的数据
- 接收TCP: 当接收TCP看到PUSH标志时,它不得在将数据传递给接收进程之前等待来自发送TCP的更多数据
重要说明:
- push功能与段边界之间没有必然关系
- 任何特定段中的数据可能是单个SEND调用 (全部或部分) 的结果,或者是多个SEND调用的结果
- push功能和PUSH标志的目的是将数据从发送用户推送到接收用户
- 它不提供记录服务 (record service)
缓冲区管理
push功能与跨越TCP/用户接口的数据缓冲区的使用之间存在耦合:
- 每次将PUSH标志与放入接收用户缓冲区的数据关联时,即使缓冲区未填满,也会将缓冲区返回给用户进行处理
- 如果在看到PUSH之前到达填充用户缓冲区的数据,则以缓冲区大小单位将数据传递给用户
紧急数据 (Urgent Data)
TCP还提供了一种方法,向数据的接收者传达在数据流中比接收者当前正在读取的点更远的某个点有紧急数据 (urgent data)。
- TCP不尝试定义用户在被通知待处理紧急数据时具体做什么
- 一般概念是接收进程将采取行动快速处理紧急数据
2.9. Precedence and Security (优先级和安全)
TCP使用互联网协议服务类型字段 (type of service field) 和安全选项 (security option),以在每个连接的基础上向TCP用户提供优先级和安全性。
多级安全环境
并非所有TCP模块都必然在多级安全环境 (multilevel secure environment) 中运行:
- 一些可能仅限于非保密使用
- 其他可能仅在一个安全级别和隔离区运行
- 因此,一些TCP实现和对用户的服务可能仅限于多级安全情况的子集
安全标记要求
在多级安全环境中运行的TCP模块必须:
- 适当地用安全性、隔离区和优先级标记传出段
- 向其用户或高层协议 (如Telnet或THP) 提供接口,以允许它们指定连接所需的安全级别、隔离区和优先级
2.10. Robustness Principle (健壮性原则)
TCP实现将遵循一般的健壮性原则:
"在你所做的事情上保持保守,在你从他人那里接受的事情上保持宽容。"
"Be conservative in what you do, be liberal in what you accept from others."
这一原则也被称为Postel's Law (Postel定律),是互联网协议设计的核心理念之一。
实践意义
- 发送: 严格遵循规范,生成格式正确的段
- 接收: 尽可能宽松地解释接收到的段,容忍轻微的格式偏差
- 兼容性: 促进不同实现之间的互操作性
- 演进: 允许协议随时间演进,同时保持向后兼容性
设计哲学总结
TCP的设计哲学可以总结为以下几个核心原则:
- 端到端可靠性 (End-to-End Reliability): 在不可靠的网络之上构建可靠的传输
- 分层设计 (Layered Design): 清晰的层次结构,职责分离
- 灵活性 (Flexibility): 支持多种网络类型和应用需求
- 健壮性 (Robustness): 能够从错误和异常情况中恢复
- 效率 (Efficiency): 流量控制和拥塞控制机制
- 简单接口 (Simple Interface): 类似文件操作的用户接口
- 宽容性 (Liberal Acceptance): Postel定律的体现
这些哲学原则指导了TCP的具体设计和实现,使其成为互联网中最成功和持久的协议之一。
下一章: 3. Functional Specification (功能规范) - TCP的详细技术规范,包括头部格式、状态机、事件处理等