TCP拥塞控制中的快重传与快恢复算法详解
字数 1828 2025-12-09 04:09:30
TCP拥塞控制中的快重传与快恢复算法详解
1. 背景与问题定义
TCP拥塞控制的核心目标是在网络拥塞时降低发送速率,避免网络崩溃,同时在拥塞解除后快速恢复传输效率。传统的慢启动和拥塞避免算法依赖超时重传作为拥塞信号,但超时机制较慢(通常需几百毫秒到几秒),可能导致吞吐量急剧下降。
快重传(Fast Retransmit) 和 快恢复(Fast Recovery) 算法应运而生,旨在更早检测丢包并快速调整拥塞窗口,减少传输中断时间。
2. 核心机制:快重传(Fast Retransmit)
2.1 触发条件
快重传的核心思想是:通过重复ACK(Duplicate ACK)提前判断数据包丢失,而不必等待超时。
- 重复ACK:接收方收到乱序数据包时,会重复发送最后一次正确顺序的ACK。
- 触发规则:当发送方连续收到 3个重复ACK(即总共4个相同ACK)时,认为该ACK对应的数据包已丢失,立即重传该数据包。
2.2 为什么是3个重复ACK?
- 1~2个重复ACK可能是由网络乱序引起(不一定丢包),3个重复ACK能较高置信度确认丢包。
- 设计权衡:过多重复ACK要求会延迟重传,过少则易误判乱序为丢包。
2.3 快重传的优点
- 避免超时等待,重传延迟从RTO(通常≥200ms)降低到约几个RTT。
- 保留更多网络吞吐量,因为重复ACK表明后续数据包仍能到达接收方,网络未完全拥塞。
3. 核心机制:快恢复(Fast Recovery)
快重传解决了重传延迟问题,但重传后如何调整拥塞窗口(cwnd)?传统超时重传会直接将cwnd设为1并进入慢启动,这过于激进(因为重复ACK表明网络仍可传输数据)。快恢复算法则更温和:
3.1 快恢复流程(以TCP Reno为例)
- 检测丢包:收到3个重复ACK,执行快重传。
- 调整阈值与窗口:
- 设 ssthresh(慢启动阈值) = 当前 cwnd / 2。
- 设 cwnd = ssthresh + 3 MSS(MSS:最大段大小)。
- 解释:加3 MSS是因为3个重复ACK表明有3个数据包已离开网络,接收方已缓存这些乱序包,窗口可适当扩大。
- 线性增长:进入拥塞避免阶段,每收到一个重复ACK,cwnd增加1 MSS(实际是“膨胀窗口”以允许发送新数据)。
- 恢复阶段:当重传包的ACK到达时,设 cwnd = ssthresh,回归正常拥塞避免(线性增长)。
3.2 为什么快恢复能提升性能?
- 避免cwnd降为1:网络仍有容量,直接重置cwnd会导致吞吐量断崖下跌。
- 平滑过渡:通过“半减后线性增长”平衡公平性与效率。
4. 算法变体:TCP NewReno 与 SACK
4.1 TCP Reno的缺陷
- 若一个窗口内多个包丢失,Reno可能多次触发快恢复,导致性能下降。
- 重传仅基于重复ACK,可能无法恢复所有丢失包。
4.2 TCP NewReno 改进
- 添加部分ACK(Partial ACK) 处理:
- 部分ACK指确认了部分重传数据,但未确认全部丢失数据的ACK。
- NewReno在部分ACK出现时,继续重传下一个疑似丢失包,避免多次进入快恢复。
- 提升多包丢失场景下的恢复效率。
4.3 基于SACK(选择性确认)的优化
- SACK允许接收方告知发送方具体丢失的数据块,发送方可精准重传多个丢失包。
- 结合快重传/快恢复,进一步减少不必要的重传和等待。
5. 实例演示(TCP Reno快恢复)
假设:
- cwnd = 20 MSS,ssthresh = 16 MSS,发送序列号1~20。
- 包5丢失,包6~20正常到达接收方。
步骤:
- 接收方收到包6(乱序),重复ACK包4(第1个重复ACK)。
- 发送方收到第3个重复ACK时(表示包5丢失),触发快重传:
- ssthresh = cwnd/2 = 10
- cwnd = ssthresh + 3 = 13
- 重传包5,继续发送新数据(若允许)。
- 当包5的ACK到达时,cwnd = ssthresh = 10,进入线性增长阶段。
6. 总结与意义
- 快重传:基于重复ACK的早期丢包检测,避免超时等待。
- 快恢复:温和调整拥塞窗口,维持网络吞吐量。
- 演进:从Reno到NewReno、SACK,算法不断优化多包丢失场景。
- 影响:快重传/快恢复是现代TCP(如Cubic、BBR)的基础组件,显著提升了高延迟、高带宽网络的性能。