TCP 可靠传输与拥塞控制
校招考察频度:☆ 中频(核心机制·协议底座) 一句话速记:可靠传输靠四件套(序号、确认应答、超时/快速重传、校验和);拥塞控制四步走:慢启动指数涨、超门限线性爬、三冗余快重传、快恢复折半走。
TCP 协议最伟大的地方在于:底层 IP 网络是不可靠、无连接、随时会丢包乱序的,而 TCP 在其上构建出了 100% 可靠的面向连接的数据流。面试主线:端到端可靠性机制 与 网络级拥塞控制算法。
一、可靠传输四大机制
| 机制 | 解决的问题 | 具体实现细节 |
|---|---|---|
| 序列号(Seq)与确认应答(ACK) | 乱序重排、报文去重 | 每个字节都有序号。接收方收到数据后返回 ACK = seq + 1,表示该序号前的数据已全部正确接收(累计确认)。 |
| 校验和(Checksum) | 报文比特损坏 | 接收方计算校验和,若与首部不一致,直接丢弃该报文,等待对端重传。 |
| 超时重传(RTO) | 恶劣网络丢包 | 发送方发出数据后启动定时器,超过 RTO(动态计算的重传超时时间) 仍未收到 ACK 则重新发送。 |
| 快速重传(Fast Retransmit) | 消除超时等待延迟 | 接收方收到乱序包时持续返回最后连续的 ACK;发送方一旦连续收到 3 个完全相同的冗余 ACK,判定该包丢失,立即重传,无需等待超时定时器清零! |
二、流量控制与滑动窗口
- 为什么需要流量控制:防止发送方发送速度过快,直接把接收方的接收缓冲区(Receive Buffer)冲垮。
- 滑动窗口机制:接收方在每次 ACK 报文中通过
Window字段通告自己当前剩余的接收缓冲区大小(接收窗口rwnd)。发送方的发送窗口不能超过rwnd。 - 零窗口死锁与解决:
- 若接收方通告
rwnd = 0,发送方暂停发送; - 随后接收方缓冲区腾空,发送了一个
rwnd = 1000的窗口更新报文,但该报文在网络中丢失了! - 双方进入死锁:发送方在等窗口更新,接收方在等数据发送。
- 解法(持续计时器 Persistence Timer):当收到零窗口通知时,发送方启动持续计时器。超时后发送一个仅含 1 字节数据的 窗口探测报文(Zero Window Probe),强制接收方重新返回当前的最新窗口大小,打破死锁。
- 若接收方通告
拥塞控制四阶段
拥塞控制: 慢启动探路, 拥塞避免巡航, 丢包减半
| 阶段 | 机制 | 目的 |
|---|---|---|
| 慢启动 | cwnd 从 1 指数增长 | 快速探测可用带宽 |
| 拥塞避免 | 到 ssthresh 后线性增长 | 避免打爆网络 |
| 快速重传/恢复 | 3 重复 ACK 触发,cwnd 减半 | 丢包不从头再来 |
| 超时重传 | 超时触发,回到慢启动 | 严重拥塞彻底退让 |
关键判断:超时 = 严重拥塞(cwnd 归 1);3 个重复 ACK = 轻度丢包(cwnd 减半)。不同丢包信号不同退让幅度。
BBR(Google):不再以丢包为拥塞信号(丢包可能只是缓冲),改用带宽和延迟测量(BDP 探测),在高速长距网络明显优于传统算法。考点了解级:知道”基于测量而非丢包”即可。
面试追问
- TCP 怎么保证可靠? 序列号 + 确认 + 重传(超时/快速重传)+ 窗口。四件套
- 快速重传为什么快? 3 个重复 ACK 立即重发,不等超时(RTO 可能上百毫秒)
- 流量控制和拥塞控制的区别? 流量控制管接收方缓冲(端到端),拥塞控制管网(全局)。窗口 = min(接收窗口, 拥塞窗口)
- 慢启动为什么指数增长? 快速探测带宽:网络好就快速冲,丢包再退让
- 超时和重复 ACK 的区别? 超时是严重拥塞(归 1 重来),重复 ACK 是轻度丢包(减半恢复)