💻CS 计算机网络
TCP 与 UDP 对比
难度:⭐ | 高频指数:🔥🔥🔥
面试回答
常见问法
- TCP 和 UDP 有什么区别?
- TCP 怎么保证可靠传输?
- 什么场景用 TCP,什么场景用 UDP?
- TCP 的流量控制和拥塞控制有什么区别?
- UDP 能不能实现可靠传输?
回答
核心区别:
| 对比项 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 可靠(确认、重传、排序) | 不可靠(尽力而为) |
| 有序性 | 保证顺序 | 不保证顺序 |
| 流量控制 | 有(滑动窗口) | 无 |
| 拥塞控制 | 有(慢启动、拥塞避免等) | 无 |
| 传输方式 | 字节流 | 数据报(有边界) |
| 头部大小 | 20-60 字节 | 8 字节 |
| 一对多 | 一对一 | 支持广播/多播 |
TCP 保证可靠传输的机制:
- 序列号:每个字节编号,接收方按序重组
- 确认应答:接收方回复 ACK 确认收到
- 超时重传:超时未收到 ACK 就重传
- 滑动窗口:流量控制,防止发送方淹没接收方
- 校验和:检测数据是否损坏
适用场景:
- TCP:文件传输、HTTP、数据库连接、邮件——需要可靠性
- UDP:视频直播、DNS 查询、游戏实时数据、IoT——需要低延迟或广播
追问
1. TCP 的流量控制 vs 拥塞控制?
- 流量控制:防止发送方发太快,接收方来不及处理。通过接收窗口(rwnd)实现,接收方在 ACK 中告知自己还能接收多少数据。
- 拥塞控制:防止网络过载。通过拥塞窗口(cwnd)实现,发送方根据网络状况动态调整发送速率。
- 实际发送窗口 = min(rwnd, cwnd)
2. UDP 能实现可靠传输吗?
可以,在应用层实现。典型例子:
- QUIC 协议(HTTP/3 的基础)
- KCP(游戏常用)
- 自定义 ACK + 重传 + 排序逻辑
本质是把 TCP 内核做的事情搬到用户态,好处是可以定制策略(如更激进的重传)。
原理展开
1. TCP 头部结构
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│ 源端口(16) │ 目的端口(16) │
├─────────────────────────────┼───────────────────────────────┤
│ 序列号(32) │
├─────────────────────────────────────────────────────────────┤
│ 确认号(32) │
├────────┼──────┼─┼─┼─┼─┼─┼─┼───────────────────────────────┤
│数据偏移│保留 │U│A│P│R│S│F│ 窗口大小(16) │
│ (4) │ │R│C│S│S│Y│I│ │
│ │ │G│K│H│T│N│N│ │
├────────┴──────┴─┴─┴─┴─┴─┴─┼───────────────────────────────┤
│ 校验和(16) │ 紧急指针(16) │
├─────────────────────────────┴───────────────────────────────┤
│ 选项(可变长) │
└─────────────────────────────────────────────────────────────┘
最小 20 字节,加上选项最大 60 字节。
2. UDP 头部结构
├───────────────────────────────┼───────────────────────────────┤
│ 源端口(16) │ 目的端口(16) │
├───────────────────────────────┼───────────────────────────────┤
│ 长度(16) │ 校验和(16) │
└───────────────────────────────┴───────────────────────────────┘
固定 8 字节,简单高效。
3. TCP 滑动窗口机制
发送方窗口:
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│已确认│已发未确认 │ 可发送 │ 不可发送 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
↑ ↑
窗口左边界 窗口右边界
- 收到 ACK → 窗口右移
- 窗口大小由接收方通告(rwnd)
- 窗口为 0 时停止发送(零窗口探测)
滑动窗口的好处:
- 不需要逐个确认,提高吞吐量
- 接收方控制发送速率
- 支持累积确认(ACK 某个序号表示之前的都收到了)
4. TCP 拥塞控制四个阶段
cwnd
│
│ ┌─── 拥塞避免(线性增长)
│ /
│ / ← ssthresh
│ /
│ /
│ / ← 慢启动(指数增长)
│ /
│ /
│/
└──────────────────────── 时间
- 慢启动:cwnd 从 1 开始,每收到一个 ACK 就 +1(实际是指数增长)
- 拥塞避免:cwnd 达到 ssthresh 后,每个 RTT 只 +1(线性增长)
- 快重传:收到 3 个重复 ACK,立即重传丢失的包(不等超时)
- 快恢复:快重传后 ssthresh = cwnd/2,cwnd = ssthresh + 3,进入拥塞避免
超时重传时:
- ssthresh = cwnd / 2
- cwnd = 1
- 重新慢启动
5. TCP 超时重传与快重传
超时重传(RTO):
- 发送数据后启动定时器
- 超时未收到 ACK 就重传
- RTO 根据 RTT 动态计算(Jacobson 算法)
快重传:
- 接收方收到乱序包时,立即发送重复 ACK
- 发送方收到 3 个重复 ACK,不等超时直接重传
- 比超时重传更快恢复
6. TCP 字节流 vs UDP 数据报
TCP(字节流):
发送:write(100B) + write(200B)
接收:可能 read 到 150B + 150B(没有边界)
UDP(数据报):
发送:sendto(100B) + sendto(200B)
接收:recvfrom 得到 100B,再 recvfrom 得到 200B(有边界)
TCP 粘包问题:
- TCP 是字节流,没有消息边界
- 应用层需要自己定义协议来分割消息
- 常见方案:固定长度、分隔符、长度前缀
7. 基于 UDP 的可靠传输协议
QUIC(Google,HTTP/3 基础):
- 0-RTT 建连(比 TCP+TLS 快)
- 多路复用无队头阻塞
- 连接迁移(换 IP 不断连)
- 用户态实现,迭代快
KCP:
- 比 TCP 更激进的重传策略
- 更小的 RTO
- 适合游戏等对延迟敏感的场景
- 牺牲带宽换低延迟
8. 选型决策树
需要可靠传输?
├── 是 → 能接受 TCP 延迟?
│ ├── 是 → TCP
│ └── 否 → UDP + 应用层可靠(QUIC/KCP)
└── 否 → 需要广播/多播?
├── 是 → UDP
└── 否 → UDP(低延迟优先)
易错点
- 说”UDP 不能可靠传输”——UDP 本身不可靠,但可以在应用层实现可靠性(QUIC、KCP)。
- 混淆流量控制和拥塞控制——流量控制是端到端的(接收方能力),拥塞控制是网络层面的。
- 说”TCP 慢启动很慢”——慢启动是指数增长,其实增长很快,只是起点小。
- 忘记 TCP 粘包问题——面试常问,要知道解决方案(长度前缀等)。
- 说”UDP 头部没有校验和”——UDP 有校验和字段(IPv4 可选,IPv6 必须)。
- 不知道 QUIC——这是近年热点,基于 UDP 实现的可靠传输协议。
记忆技巧
- TCP 五大可靠机制:序(序列号)、确(确认)、重(重传)、窗(滑动窗口)、校(校验和)
- 拥塞控制四阶段:慢启动 → 拥塞避免 → 快重传 → 快恢复
- TCP vs UDP 一句话:TCP 可靠但重,UDP 快但不管
- 头部大小:TCP 20+,UDP 8
- 选型口诀:可靠选 TCP,实时选 UDP,又要可靠又要快选 QUIC
面试速答版
TCP 面向连接、可靠、有序、字节流,头部 20 字节起;UDP 无连接、不可靠、有边界、数据报,头部 8 字节。TCP 通过序列号、确认应答、超时重传、滑动窗口保证可靠传输。流量控制通过接收窗口防止淹没接收方,拥塞控制通过拥塞窗口防止网络过载,实际发送窗口取两者最小值。拥塞控制经历慢启动(指数增长)和拥塞避免(线性增长),丢包时快重传+快恢复。UDP 可以在应用层实现可靠传输(如 QUIC、KCP)。TCP 适合需要可靠性的场景,UDP 适合实时性要求高或需要广播的场景。
Related · 计算机网络