计算机网络经典问题透视——简述TCP拥塞控制算法中的快重传和快恢复

摘要

在浩瀚的计算机网络世界中,TCP协议以其可靠性著称,而其核心的拥塞控制机制则是保障网络稳定运行的基石。在经典的拥塞控制"四件套"------慢启动(Slow Start)、拥塞避免(Congestion Avoidance)、快重传(Fast Retransmit)和快恢复(Fast Recovery)中,后两者扮演着应对网络丢包、快速恢复传输效率的关键角色。

一、问题的提出:超时重传(RTO)的局限性

在TCP的早期版本(如Tahoe)中,当发送方发送的数据包丢失时,它主要依赖 **超时重传(Retransmission Time-Out, RTO)**‍ 机制来发现和处理丢包 。发送方为每个已发送但未确认的数据包启动一个计时器。如果在计时器超时之前没有收到相应的ACK,发送方就认为该数据包已经丢失,并重新发送它。

然而,RTO机制存在一个显著的弊端:等待时间过长。RTO的计算通常基于往返时间(RTT)的动态估算,其值往往远大于一个RTT。在网络状况尚可,只是偶尔发生丢包的情况下,漫长的等待会导致TCP连接的吞吐量急剧下降,造成不必要的网络资源浪费和用户体验下降 。网络并没有陷入严重拥塞,仅仅是一个数据包的丢失就触发了长时间的"停摆",这显然是低效的。

为了解决这一问题,网络先驱们思考:能否在RTO超时之前,更早地"感知"到丢包的发生呢?答案是肯定的,而线索就隐藏在接收方返回的ACK中。

二、快重传(Fast Retransmit):基于冗余ACK的敏锐洞察

2.1 核心思想与触发条件

快重传算法的核心思想是利用接收方发送的 **冗余ACK(Duplicate ACKs)**‍ 来推断数据包的丢失 。TCP的ACK机制是累积确认的,即一个ACK号为N的确认包,表示序列号小于N的所有数据都已正确接收。

设想一个场景:发送方连续发送了Seq=1, Seq=2, Seq=3, Seq=4, Seq=5的数据包。如果Seq=2的数据包在网络中丢失,但Seq=3, Seq=4, Seq=5都成功到达了接收方。

  1. 接收方收到Seq=1,返回ACK=2。
  2. Seq=2丢失。
  3. 接收方收到Seq=3,发现它不是期望的Seq=2。根据累积确认原则,它只能再次发送对已收到的最后一个连续数据包的确认,即再次发送ACK=2。这是一个冗余ACK。
  4. 接收方收到Seq=4,同样不是期望的Seq=2,于是再次发送ACK=2。这是第二个冗余ACK。
  5. 接收方收到Seq=5,继续发送ACK=2。这是第三个冗余ACK。

发送方在收到一个正常的ACK后,如果紧接着收到了三个或以上连续的、针对同一个数据包的冗余ACK,就可以做出一个合理的推断:在这个ACK所期望的序列号之后的数据包已经到达了接收方,而唯独这个序列号的数据包很可能在传输途中丢失了 。因为如果仅仅是网络乱序,通常不会导致连续三个后续包先于一个包到达。

因此, ‍**"连续收到三个冗余ACK"**‍ 成为了触发快重传的经典条件 。

2.2 工作流程

当快重传条件被触发时,发送方会执行以下操作:

  1. 立即重传:不等RTO计时器超时,立即重传那个被冗余ACK所指示的丢失的数据包(在上例中就是Seq=2)。
  2. 不进入慢启动:与RTO超时后会将拥塞窗口(cwnd)降为1并进入慢启动不同,快重传认为网络并未发生严重拥塞,只是个别丢包。因此,它不会重置cwnd,而是启动快恢复阶段。

快重传算法的引入,使得TCP在RTO发生之前就能对丢包做出快速响应,极大地提高了网络吞吐量和传输效率,尤其是在高延迟、高带宽的网络环境中 。

三、快恢复(Fast Recovery):拥塞窗口的精细化调整

快重传解决了"何时重传"的问题,而快恢复则解决了"重传后该怎么做"的问题。如果快重传后依然像RTO超时一样将cwnd降为1,那么快重传带来的性能提升将大打折扣。快恢复算法的目标是在丢包发生后,以一种不那么"激进"的方式降低发送速率,并尽快恢复到正常传输水平 。

快恢复算法最早在TCP Reno版本中被引入和规范 。其工作流程如下:

  1. 调整拥塞阈值(ssthresh) ‍ :当发送方收到3个冗余ACK时,它会将慢启动阈值ssthresh设置为当前拥塞窗口cwnd的一半。这是一个"乘性减"的过程,体现了对网络拥塞的响应。
    ssthresh = cwnd / 2

  2. 调整拥塞窗口(cwnd) ‍ :发送方将cwnd设置为新的ssthresh值(在一些实现中是ssthresh + 3*MSS),而不是降为1。这反映了算法的判断:既然还有数据包能到达接收方(否则不会有冗余ACK),说明网络中仍有可用带宽 。
    cwnd = ssthresh (或 ssthresh + 3*MSS)

  3. 进入拥塞避免阶段 :完成上述调整后,TCP直接跳过慢启动阶段,进入拥塞避免 状态。此时,发送方认为网络中"正在路上"的数据包数量约为新的cwnd值。

  4. ‍**"膨胀"窗口** :在快恢复阶段,每当再收到一个冗余ACK时,cwnd会临时增加一个MSS(Maximum Segment Size)。这个过程被称为"窗口膨胀"(inflating the window)。这样做的目的是为了在网络恢复期间,允许发送方传输新的数据包,以填补因旧数据包离开网络而产生的空隙,从而保持网络管道的"充满"状态,提高效率 。

  5. 退出快恢复 :当发送方收到一个新的ACK (即确认了之前重传的数据包以及之后所有数据的ACK)时,它就认为丢包恢复过程已经完成。此时,它会将cwnd重新设置为之前计算出的ssthresh值,并正式进入标准的拥塞避免算法流程(cwnd每个RTT线性增加一个MSS) 。

四、代码实现层面的观察

虽然我们无法在此展示完整的内核源码,但从公开的分析资料中可以窥见快重传和快恢复在Linux内核中的实现脉络。这些逻辑主要集中在TCP协议栈的输入处理部分,如net/ipv4/tcp_input.c文件中 。

一个名为tcp_fastretrans_alert的函数是处理快重传和快恢复的核心入口 。当TCP栈接收到一个ACK包时,相关代码会检查它是否是冗余ACK。如果冗余ACK的计数器(如tp->dup_ack)达到了阈值(通常是3),就会调用tcp_fastretrans_alert

在该函数内部,会执行一系列操作,包括:

  • 将拥塞状态切换到恢复状态(TCP_CA_Recovery) 。
  • 调用拥塞控制模块的函数来降低ssthreshcwnd
  • 标记需要重传的数据包,并可能调用位于net/ipv4/tcp_output.c中的tcp_retransmit_skb等函数来执行实际的重传操作 。

整个过程体现了内核协议栈的模块化设计,由输入处理、状态机管理和数据输出等多个部分协同完成。

五、算法的演进与现代视角

快重传和快恢复机制极大地优化了TCP性能,但经典的Reno算法在面对多个数据包连续丢失的场景时仍有不足。Reno在收到一个新的ACK后会立即退出快恢复阶段,如果此时还有其他数据包丢失,它只能等待下一次RTO超时 。

为了解决这个问题,后续的TCP版本进行了改进:

  • NewReno:作为Reno的直接改进版,NewReno优化了快恢复阶段。它在收到部分确认(Partial ACK)时不会立即退出恢复状态,而是会继续重传后续可能丢失的数据包,直到所有在进入快恢复状态前发出的数据都被确认为止。这显著提高了处理突发性、多包丢失场景的效率 。

  • **SACK(Selective Acknowledgment)**‍ :SACK机制允许接收方在ACK中明确告知发送方哪些非连续的数据块已经被接收。这为发送方提供了更精确的丢包信息,使其可以一次性重传所有已知的丢失数据包,避免了NewReno中逐个推断和重传的低效过程 。

与新兴拥塞控制算法的对比

进入21世纪20年代,随着网络环境的巨大变迁(高带宽、长延迟、高丢包率的无线网络),传统的基于丢包(Loss-based)的拥塞控制算法(如Reno、CUBIC)显示出局限性。它们将丢包等同于拥塞,但在无线网络中,丢包可能仅仅是信号干扰所致,而非网络拥塞。

以Google的 **BBR(Bottleneck Bandwidth and Round-trip propagation time)**‍ 为代表的新兴算法,采用了不同的思路 。BBR不依赖丢包作为拥塞信号,而是主动探测网络的瓶颈带宽和最小RTT,通过建立网络模型来动态调整发送速率 。

  • 性能对比:大量研究和基准测试表明,在存在一定丢包率的网络中,BBR的吞吐量和延迟表现通常优于CUBIC和Reno 。BBR能够更好地区分拥塞丢包和随机丢包,从而在高丢包网络下维持较高的吞吐量 。而Reno/CUBIC中的快重传/快恢复机制,虽然高效,但其触发前提仍然是"感知到丢包",这使得它们在面对非拥塞丢包时会做出不必要的速率下调。

尽管如此,快重传和快恢复作为TCP拥塞控制体系中的经典组件,其设计思想------通过冗余信息快速推断状态并做出适应性调整------至今仍具有深远的指导意义。它们是理解现代更复杂拥塞控制算法(如CUBIC仍然内建了这些机制)演进的基石。

六、结论

快重传和快恢复算法是TCP协议发展史上的一个重要里程碑。它们通过巧妙地利用冗余ACK,实现了在超时重传发生前对网络丢包的快速响应和恢复,显著提升了TCP在大多数网络环境下的性能。从Reno到NewReno再到SACK,这些机制不断演进,变得更加智能和高效。尽管BBR等新兴算法正在改变拥塞控制的游戏规则,但深入理解快重传和快恢复这一经典组合,对于我们掌握网络协议的设计哲学、诊断网络性能问题以及 appreciating 现代网络技术的演进脉络,依然至关重要。

相关推荐
不悔哥2 小时前
路由器特性——网络状态检测
linux·c语言·网络·tcp/ip·智能路由器
win10系统2 小时前
网络速度慢、频繁断网的解决办法
网络·智能路由器
初圣魔门首席弟子2 小时前
HTTP 服务器项目学习笔记
网络
_不会dp不改名_2 小时前
HCIP笔记8--中间系统到中间系统协议1
网络·笔记·hcip
真正的醒悟2 小时前
图解网络10
网络·智能路由器
拾忆,想起2 小时前
Dubbo服务访问控制(ACL)完全指南:从IP黑白名单到自定义安全策略
前端·网络·网络协议·tcp/ip·微服务·php·dubbo
jennychary12 小时前
网工学习笔记:loopback 和route id
网络·笔记·学习
blackorbird2 小时前
美国紧急通信系统:保障国家紧急状态下通信畅通
网络
人工智能训练2 小时前
openEuler系统中home文件夹下huawei、HwHiAiUser、lost+found 文件夹的区别和作用
linux·运维·服务器·人工智能·windows·华为·openeuler