第 5 章:传输层 —— 数据的"可靠快递"¶
场景: 网络层把数据包送到了目标主机。但一台主机上同时运行着浏览器、微信、游戏……数据包该交给哪个程序?如果数据包在路上丢了怎么办?传输层用"端口号"和"可靠传输机制"解决这些问题。
5.1 传输层的两大职责¶
核心比喻:传输层就是快递公司的"签收确认"服务
网络层只负责把包裹送到小区门口(目标主机)。传输层负责:
- 找到具体收件人 (端口号)—— 小区里住了很多人,包裹上必须写清楚收件人姓名
- 确保包裹完好送达 (可靠传输)—— 挂号信模式:签收确认、丢件重发、按序送达
5.2 端口号 —— 应用的"门牌号"¶
端口号是 16 位整数(0~65535),用于标识主机上的具体应用进程:
| 端口范围 | 类型 | 示例 |
|---|---|---|
| 0~1023 | 知名端口(Well-known) | HTTP:80、HTTPS:443、DNS:53、SSH:22、FTP:21 |
| 1024~49151 | 注册端口 | MySQL:3306、Redis:6379、Tomcat:8080 |
| 49152~65535 | 动态/私有端口 | 客户端临时使用 |
IP地址 + 端口号 = 套接字(Socket)
192.168.1.10:80 ← Web 服务器在监听 80 端口
192.168.1.10:3306 ← MySQL 数据库在监听 3306 端口
192.168.1.10:22 ← SSH 服务在监听 22 端口
5.3 UDP —— 无连接的"明信片"¶
核心比喻:UDP 就像寄明信片
你写一张明信片扔进邮筒——不确认对方是否收到,不保证按顺序到达,丢了也不重发。但好处是:快、简单、开销小。
UDP 适合对实时性要求高但能容忍少量丢包的场景:视频通话、直播、在线游戏、DNS 查询。
UDP 报文格式¶
0 7 8 15 16 23 24 31
┌────────┬────────┬────────┬────────┐
│ 源端口 │ 目的端口 │ 长度 │ 校验和 │
├────────┴────────┴────────┴────────┤
│ 数据 │
└────────────────────────────────────┘
UDP 头部仅 8 字节,极其精简。
| 特点 | 说明 |
|---|---|
| 无连接 | 发送前不需要建立连接 |
| 不可靠 | 不保证送达、不保证顺序 |
| 无拥塞控制 | 可以按任意速率发送 |
| 低开销 | 头部仅 8 字节 |
| 支持广播/组播 | TCP 不支持 |
5.4 TCP —— 面向连接的"挂号信"¶
核心比喻:TCP 就像寄挂号信
你寄一封挂号信:
- 先打电话确认对方在家( 三次握手建立连接 )
- 每封信都有编号,对方收到后签字确认( 确认应答 + 序列号 )
- 如果对方没签收,你重新寄一封( 超时重传 )
- 信全部寄完后,双方确认"都收到了"再挂电话( 四次挥手释放连接 )
TCP 报文格式¶
0 7 8 15 16 23 24 31
┌────────┬────────┬────────┬────────┐
│ 源端口 │ 目的端口 │ │
├────────┴────────┤ 序列号(SEQ) │
│ │ │
├─────────────────┴────────┬────────┤
│ 确认号(ACK) │ │
├────────┬────────┬────────┼────────┤
│ 数据偏移 │ 保留/标志│ 窗口大小 │ │
├────────┴────────┴────────┴────────┤
│ 校验和 │ 紧急指针 │
├─────────────────────┴─────────────┤
│ 选项(可变长度) │
└───────────────────────────────────┘
TCP 标志位¶
| 标志 | 全称 | 作用 |
|---|---|---|
| SYN | Synchronize | 建立连接时同步序列号 |
| ACK | Acknowledgment | 确认收到数据 |
| FIN | Finish | 请求释放连接 |
| RST | Reset | 强制重置连接 |
| PSH | Push | 催促接收方尽快交付应用层 |
| URG | Urgent | 紧急数据指针有效 |
5.5 TCP 三次握手¶
客户端 服务器
│ │
│──── SYN=1, seq=x ────────────→│ 第1次:客户端请求建立连接
│ │
│←── SYN=1, ACK=1, seq=y, │ 第2次:服务器同意并确认
│ ack=x+1 ──────────────────│
│ │
│──── ACK=1, seq=x+1, ack=y+1 ─→│ 第3次:客户端确认
│ │
│ ✅ 连接建立,开始传输数据 │
为什么是三次握手而不是两次?
防止已失效的连接请求报文突然传到服务器,导致服务器错误地建立连接。
如果只有两次握手:客户端发了一个连接请求,但这个请求在网络中滞留了很久。客户端等不及就重发了请求,成功建立连接、传输数据、释放连接。之后那个滞留的旧请求到达服务器——服务器以为客户端又要建立连接,就同意了。但客户端根本没这个意图,服务器白白浪费资源。
5.6 TCP 四次挥手¶
客户端 服务器
│ │
│──── FIN=1, seq=u ────────────→│ 第1次:客户端说"我说完了"
│ │
│←── ACK=1, seq=v, ack=u+1 ────│ 第2次:服务器说"知道了"
│ │
│ (服务器可能还有数据要发) │
│ │
│←── FIN=1, ACK=1, seq=w, │ 第3次:服务器说"我也说完了"
│ ack=u+1 ──────────────────│
│ │
│──── ACK=1, seq=u+1, ack=w+1 ─→│ 第4次:客户端说"好的,再见"
│ │
│ ⏱ 等待 2MSL 后关闭 │ 服务器收到 ACK 后立即关闭
为什么是四次挥手而不是三次?
因为 TCP 是全双工的——双方都可以独立地发送和接收数据。当客户端说"我说完了"(FIN),服务器可能还有数据要发送,所以服务器先确认收到(ACK),等自己的数据也发完了再发送 FIN。因此需要四次交互。
5.7 TCP 流量控制与拥塞控制¶
流量控制 —— 滑动窗口¶
核心比喻:滑动窗口就像快递员的送货节奏
快递员一次能搬 10 个包裹(窗口大小 = 10)。送到 5 个后,收件人说"先别送了,我仓库满了"(窗口缩小到 0)。等仓库腾出空间,收件人说"可以再送 3 个"(窗口调整为 3)。
| 机制 | 作用 |
|---|---|
| 滑动窗口 | 接收方通过"窗口大小"字段告诉发送方自己还能接收多少数据 |
| 窗口为 0 | 发送方暂停发送,直到收到窗口更新 |
| 持续计时器 | 防止窗口更新报文丢失导致死锁 |
拥塞控制¶
| 算法 | 阶段 | 说明 |
|---|---|---|
| 慢启动 | 连接建立初期 | 拥塞窗口指数增长(1→2→4→8...) |
| 拥塞避免 | 达到阈值后 | 拥塞窗口线性增长(+1) |
| 快重传 | 收到 3 个重复 ACK | 立即重传丢失的报文段 |
| 快恢复 | 快重传后 | 不降到慢启动,而是降到新阈值 |
5.8 常见考试题型¶
例题 1: TCP 协议通过( )机制保证可靠传输。
A. 三次握手 B. 确认应答与超时重传 C. 端口号 D. IP 地址
查看答案
答案:B
TCP 的可靠传输核心机制是确认应答(ACK)和超时重传。三次握手是建立连接的机制,端口号用于标识应用进程,IP 地址是网络层的寻址方式。
例题 2: TCP 连接释放需要( )次握手。
A. 2 B. 3 C. 4 D. 5
查看答案
答案:C
TCP 是全双工通信,每个方向都需要单独关闭。客户端发送 FIN(第 1 次),服务器回复 ACK(第 2 次),服务器发送 FIN(第 3 次),客户端回复 ACK(第 4 次),共四次。
例题 3: 以下关于 UDP 的描述,正确的是( )。
A. 提供可靠传输 B. 面向连接 C. 头部开销小 D. 支持流量控制
查看答案
答案:C
UDP 是无连接的、不可靠的传输协议,不提供流量控制和拥塞控制。其最大优势是头部仅 8 字节,开销极小,适合实时应用。
要点总结¶
- 端口号(065535)标识应用进程,01023 为知名端口
- UDP:无连接、不可靠、低开销,适合实时应用
- TCP:面向连接、可靠传输,通过序列号+确认+重传保证
- 三次握手建立连接(SYN → SYN+ACK → ACK)
- 四次挥手释放连接(FIN → ACK → FIN → ACK)
- 滑动窗口实现流量控制,慢启动/拥塞避免实现拥塞控制
课后练习¶
-
握手分析 :画出 TCP 三次握手过程中,每次交互的 SYN、ACK 标志位和序列号的变化。
-
协议选择 :以下场景分别适合用 TCP 还是 UDP?为什么?
- 文件传输
- 视频直播
- 电子邮件
- DNS 域名查询
-
真题演练 :TCP 的流量控制是通过( )机制实现的。
下一章预告: 传输层解决了"可靠送达"的问题。最上层——应用层——是我们每天使用的 HTTP、DNS、电子邮件等协议。第 6 章见。