TCP的MACK(重复确认)与快速重传机制详解
字数 1788 2025-11-07 12:33:56
TCP的MACK(重复确认)与快速重传机制详解
1. 问题背景
在TCP通信中,接收方每收到一个数据段,会回复一个ACK(确认)报文,告知发送方“已成功接收某个序列号之前的数据”。但如果接收方收到乱序的数据段(例如先收到序列号1000-2000的数据,却未收到序列号500-1000的数据),可能会触发重复确认(Duplicate ACK),进而引发快速重传(Fast Retransmit)。
2. 重复确认(Duplicate ACK)的产生
假设发送方连续发送3个数据段:
- 段1: Seq=1000, Len=1000
- 段2: Seq=2000, Len=1000
- 段3: Seq=3000, Len=1000
若接收方收到段1(Seq=1000)后,回复ACK=2000(期望下一个序列号为2000)。但段2因网络延迟未到达,而段3先到达:
- 接收方检查段3的Seq=3000,发现不是期望的Seq=2000,于是立即回复ACK=2000(重复之前的确认号)。
- 重复ACK的含义是:“我仍然在等待序列号2000的数据,请尽快补发”。
关键规则:
- 只有收到乱序且不重复的数据段时,才会发送重复ACK。
- 重复ACK的确认号总是等于当前已连续接收的最大序列号+1(即期望的下一个序列号)。
3. 快速重传的触发条件
发送方收到3个或以上重复ACK时,会认为该ACK对应的数据段已丢失(而非延迟),并立即重传该数据段,无需等待超时计时器(RTO)到期。这一机制称为快速重传。
为什么是3个重复ACK?
- 1个重复ACK可能因网络乱序偶然触发。
- 连续3个重复ACK表明后续数据段能正常到达,但中间某个段极可能丢失(排除短暂乱序)。
- 这一阈值平衡了误判风险和重传速度。
4. 快速重传的详细流程
步骤1:检测重复ACK
发送方维护一个“重复ACK计数器”,每收到一个重复ACK,计数器加1。
步骤2:触发重传
当计数器达到3时:
- 立即重传重复ACK对应序列号的数据段(如上例中的Seq=2000段)。
- 进入快速恢复(Fast Recovery)阶段(见后续说明)。
步骤3:更新拥塞控制
- 传统TCP(Tahoe版本)会直接将拥塞窗口(cwnd)设为1,进入慢启动。
- 改进版TCP(Reno等)会执行快速恢复,避免过度降低传输效率。
5. 快速恢复机制简介
在快速重传后,发送方执行快速恢复:
- 将拥塞窗口减半(cwnd = cwnd/2),并设置慢启动阈值(ssthresh)= cwnd。
- 每收到一个重复ACK,将cwnd略微扩大(模拟新数据被确认),维持流量发送。
- 当收到新数据的ACK时,退出快速恢复,将cwnd设为ssthresh,进入拥塞避免阶段。
6. 示例场景
假设发送方窗口内有数据段Seq=1000~4000,段2000丢失:
- 接收方收到段1000后回复ACK=2000。
- 收到段3000(乱序)时,回复重复ACK=2000。
- 收到段4000(乱序)时,再次回复重复ACK=2000。
- 发送方收到第3个重复ACK=2000后,立即重传段2000。
- 接收方收到段2000后,回复ACK=5000(确认所有连续数据)。
7. 与超时重传的对比
| 特性 | 快速重传 | 超时重传(RTO超时) |
|---|---|---|
| 触发条件 | 3个重复ACK | 超时计时器到期 |
| 响应速度 | 快(无需等待超时) | 慢(至少等待一个RTO) |
| 对拥塞的判断 | 轻度拥塞(个别包丢失) | 严重拥塞(链路或路由问题) |
| 窗口调整策略 | 快速恢复(cwnd减半) | 慢启动(cwnd重置为1) |
8. 总结
- 重复ACK是TCP应对乱序或丢包的重要信号。
- 快速重传通过重复ACK提前触发重传,减少对超时机制的依赖,提升传输效率。
- 结合快速恢复机制,可在避免拥塞恶化的同时维持较高吞吐量。