目录
1. 滑动窗口的统一框架
2. RTT估算:从简单到强健的演进
2.1 重传超时计算的核心矛盾
2.2 EWMA估算的脆弱性
2.3 Jacobson/Karels算法:引入方差估计
2.4 Karn算法:重传样本的歧义排除
3. 快速重传:以ACK推断丢包
3.1 累计确认的信息缺失
3.2 三个重复ACK的触发条件
3.3 与超时重传的互补
4. SACK:精确反馈与管道效率
4.1 累计确认在批量丢失下的失效
4.2 SACK选项的结构
4.3 管道化传输的性能恢复
5. 机制的协同与耦合
6. 结语
参考文献
1. 滑动窗口的统一框架
TCP的可靠传输由三个机制协同实现:序号管理标记字节流的每个偏移,确认机制反馈接收进度,超时重传兜底处理丢失。这三个机制在滑动窗口框架下被统一协调。
发送端维护一个发送窗口,窗口内字节可分为四类:已发送且已确认(可从缓冲区移除)、已发送但未确认(需缓存待重传)、未发送但在窗口内允许发送(可立即发送)、未发送且超出窗口(需等待窗口滑开)。接收端维护一个接收窗口,声明自己缓冲区剩余空间,控制发送端窗口上限,实现流量控制。
窗口随着ACK到达向前滑动——确认号推进窗口左沿,接收窗口通告推进窗口右沿。滑动原语极简,但其行为受RTT估算、拥塞窗口和接收通告窗口三重约束:实际发送窗口取拥塞窗口和接收通告窗口的较小值。
滑动窗口的设计核心完成两项不同的功能:发送端一侧,窗口控制待确认数据的最大量(管道深度);接收端一侧,窗口通告控制发送端速率与接收端处理能力匹配。两项功能通过同一个窗口概念耦合,理解这种耦合是诊断高延迟网络中吞吐量瓶颈的关键——到底是ACK返回太慢导致窗口停滞,还是接收方缓冲区满导致窗口通告归零。
2. RTT估算:从简单到强健的演进
2.1 重传超时计算的核心矛盾
重传超时(RTO)必须略大于当前网络往返时间(RTT)。RTO设得太短,正常延迟波动会被误判为丢包,触发伪造重传——发送端在网络并未丢包时将已发送段重复发送。伪造重传加重链路负载,在高延迟路径上自我诱发拥塞。RTO设得太长,真正的丢包迟迟得不到重传,接收端阻塞等待,吞吐量断崖式下降。
这个核心矛盾决定了RTT估算精度是TCP可靠性的基础。问题在于RTT本身不是常数——多跳路径动态变化、路由器排队延迟随负载波动、无线重传引入突发延迟峰值。RTT估算算法必须既跟踪RTT趋势,又能容忍偶尔的突发延迟而不误判。
2.2 EWMA估算的脆弱性
TCP最初使用指数加权移动平均(EWMA)维持一个平滑RTT估计值。每当收到一个新数据段的ACK时,采样本次RTT样本,与旧估计值做衰减混合——新估计值取旧估计值的绝大部分加新样本的一小部分。衰减因子决定了旧估计值对突发延迟的敏感程度:因子小则平滑但跟踪变化慢,因子大则反应快但容易被单次高延迟样本扰动。
EWMA的脆弱性在于它只跟踪水平,不跟踪波动性。当RTT从稳定变为持续高抖动时,固定的衰减因子使RTO跟不上实际延迟分布的变化。在拥塞丢包后,发送端等待重传超时,却不知道下一轮重传后链路状况是恢复正常还是持续拥塞——单靠EWMA无法给出合理的延迟预估。
2.3 Jacobson/Karels算法:引入方差估计
1988年,Van Jacobson和Mike Karels提出TCP的RTT估算必须引入方差分量。他们的核心洞察是:RTO不能只取决于RTT均值,还必须取决于RTT的波动程度——在网络抖动大时应拉长RTO,在网络稳定时应缩短RTO。
Jacobson/Karels算法维护两个状态变量:平滑RTT估计值srtt,以及平滑RTT均值偏差rttvar。每次采样新RTT样本时,srtt的更新与EWMA类似,rttvar跟踪新样本与srtt偏差的平滑绝对值。RTO取srtt加四倍rttvar。
当网络稳定、RTT近乎常数时,rttvar接近零,RTO紧贴RTT——延迟最小。当网络抖动增加、RTT出现大起大落时,rttvar迅速上升,RTO自动拉长,减少伪重传。四倍系数是基于RTT偏差近似正态分布假设得出的经验值——在均值的四倍标准差内几乎覆盖所有合法波动。
Jacobson/Karels算法已成为每个TCP实现的标配,其成功在于认识到:在拥塞不稳定的网络中,方差信息比均值信息更重要。
2.4 Karn算法:重传样本的歧义排除
当一个段被重传后收到ACK,发送端面临一个歧义:这个ACK确认的是原始段还是重传段?如果确认的是原始段——即原始段只是延迟较高并非丢失——采样重传段的RTT将严重高估,导致RTO不必要地扩大。
Karn算法直接排除所有重传段的RTT样本——只对原发数据段的ACK做RTT采样。重传超时后使用指数退避策略——RTO逐次倍增,直至达到上限。Karn算法的代价是,在多个连续丢包期间RTT估算没有被更新,但RTO的指数退避确保了即使估算值过时,重传仍能继续推进。
3. 快速重传:以ACK推断丢包
3.1 累计确认的信息缺失
累计确认是一种带宽有效但信息贫乏的反馈模式。确认号N意味着字节N之前的所有字节均已正确接收,但无法告知发送端哪一段具体丢失。考虑发送端连续发出1-1000、1001-2000、2001-3000三段。第三段顺利到达,但第二段丢失。接收方收到乱序的2001-3000段后,根据累计确认规则只能回复ACK=1001(期望接收1-1000段的下一个字节,且第二段缺失仍阻塞窗口推进)。
仅有普通累计确认,发送端无法区分第二段丢失与仅延迟到达。这是滑动窗口协议在乱序网络中的信息瓶颈。
3.2 三个重复ACK的触发条件
快速重传机制利用重复ACK作为丢包信息源。当接收方收到一个乱序段时,它产生一个重复ACK,确认号为它仍期望接收的下一个连续字节。后续再到达的乱序段中,每个都会产生一个新的重复ACK,确认号不变。
当发送端收到第三个重复ACK(即总计四个相等确认号的ACK),TCP认定对应序号的段已丢失,立即执行重传,不等超时计时器到期。选择第三个重复ACK作为阈值,是经验上排除了短暂的段重排序——网络中单次段重排通常产生一到两个重复ACK,但三个以上强烈暗示该段确实丢失而非仅乱序。
3.3 与超时重传的互补
快速重传与超时重传是TCP的"快路径"与"慢路径"。快速重传在收到足够重复ACK时立即触发,延迟远小于RTO。它使TCP在偶尔丢包但大体畅通的网络中保持管道满——传统TCP Tahoe在没有快速重传的情况下,一个丢包就意味着RTO级别的延迟和慢启动的重新进入。
快速重传后进入的拥塞控制流程——快速恢复——不再将拥塞窗口降为1,而是降为原来的一半,保持管道中仍有可发送的数据。这是TCP Reno相对于Tahoe的关键改进,快速重传提供了触发快速恢复的信号,二者协同使管道化传输在偶发丢包时仍然能够维持可观的吞吐量。
4. SACK:精确反馈与管道效率
4.1 累计确认在批量丢失下的失效
累计确认在单个窗口内仅丢失一个段时,配合快速重传足以恢复。但当一个窗口内丢失多个段时,累计确认的信息瓶颈暴露。
发送端发出八段,第二、第五、第七段丢失。接收方陆续收到乱序段返回重复ACK,确认号始终停在第二段处。发送端快速重传第二段后,希望在收到第二段ACK后能了解后续丢失段状况。但第二段的ACK确认号仅推进到第五段——第五段仍然缺失。发送端需要逐一等待每个丢失段的三个重复ACK或RTO超时,管道被反复停滞。在长管道高带宽延迟网络中,窗口内多段丢失成为吞吐量的隐形杀手。
4.2 SACK选项的结构
选择确认(SACK)允许接收方在ACK段中附加已成功接收的字节块范围。SACK块是一个起始和结束序号的元组列表,每个块标识一个连续接收但尚不能确认的字节区间(因为更早的字节仍缺失)。
在同样八段两段丢失的场景中,接收方在每个重复ACK中附加SACK块——报告已成功接收的乱序段范围。发送端结合累计确认号与SACK块,可以精确推断窗口中哪些段丢失、哪些已可安全从重传缓冲区移除。发送端为每个丢失段各发送一次重传,而不是每次都等待新的DUP ACK或RTO。
4.3 管道化传输的性能恢复
SACK对吞吐量的影响在长粗管道中最为显著。跨洲光纤链路上,RTT为100ms,带宽为1Gbps,BDP约为12.5MB。TCP窗口内可包含数千个段,窗口内同时丢失多个段的概率不能忽略。
无SACK时,恢复需要多轮快速重传或更差的RTO介入,有效吞吐量可能降至链路容量的一小部分。有SACK时,发送端在一轮RTT内重传所有已识别丢失的段,管道近乎持续满载。SACK将丢包对管道效率的破坏从窗口级降低到段级——代价是接收端和发送端均需维护SACK信息结构,增加了控制逻辑的复杂度。
5. 机制的协同与耦合
滑动窗口框架中的可靠传输机制彼此耦合,理解协同边界有助于定位性能瓶颈。
RTT估算驱动超时重传的时间间隔。快速重传在丢包数较少时跳过RTO延迟,在窗口内仅一两个段丢失时表现极优。SACK辅助快速重传,将批量丢失场景识别为可并行的重传调度问题。RTO仍在SACK无法覆盖的极端丢失(如整个窗口的ACK反馈消失)时作为最终兜底——没有持续的重复ACK流意味着无法触发快速重传,只能依赖超时计时器。
窗口大小是这些机制的上限约束。无论SACK能够多么精确地识别丢失段,如果接收窗口或拥塞窗口本身太小,管道深度受限,吞吐量的上限已经锁定。在高BDP网络中,窗口规模本身往往就是性能瓶颈——需要窗口缩放选项将窗口从16位扩展到更大范围——在讨论可靠传输机制之前,这个条件首先满足。
6. 结语
TCP在滑动窗口框架上构建了一套分层协作的可靠性保障体系。RTT估算算法从固定加权演进到Jacobson/Karels方差估计,解决了重传超时在高抖动网络中的可靠性问题。快速重传以重复ACK为推断信号,在不等待超时的情况下执行丢包重传,将偶发丢包的恢复延迟从秒级降到RTT级别。SACK以精确的接收块反馈替代累计确认的部分信息损失,将多段丢失场景下管道化传输的性能从窗口级压缩恢复到段级恢复。
这一组机制的演进过程反映了一个更深层的方法论:可靠传输协议的设计根本上是在信息反馈的精度与控制开销之间不断寻求针对不同丢包模式的更优平衡。
参考文献
[1] Jacobson, V. Congestion avoidance and control.ACM SIGCOMM CCR, 18(4): 314-329, 1988.
[2] Karn, P., & Partridge, C. Improving round-trip time estimates in reliable transport protocols.ACM SIGCOMM CCR, 17(5): 2-7, 1987.
[3] Mathis, M., Mahdavi, J., Floyd, S., & Romanow, A. RFC 2018: TCP Selective Acknowledgment Options. IETF, 1996.
[4] Fall, K. R., & Stevens, W. R. *TCP/IP Illustrated, Volume 1: The Protocols* (2nd ed.). Addison-Wesley, 2011.