本文目录导读:

- 超时重传 —— 最原始、最可靠的检测
- 快速重传 —— 更积极的检测
- Forward ACK (FACK) —— 更精细的检测
- Selective ACK (SACK)—— 高效处理连续丢包
- 时间戳选项 —— 更精确的 RTT/RTO 计算
- 总结与对比
- 实际开发或排查中如何观察丢包?
TCP 通过多种机制来检测丢包,主要分为被动检测和主动检测两大类,核心原理是依赖于序列号和确认号。
以下是 TCP 丢包检测的主要方法,从最常见到较详细:
超时重传 —— 最原始、最可靠的检测
这是 TCP 最基本的丢包检测机制,基于一个定时器。
- 原理:
- 发送方发送一个数据段(Segment),并启动一个重传计时器。
- 发送方在计时器到期前,等待接收方发回的确认包(ACK)。
- 如果计时器超时,仍未收到对应的 ACK,发送方就默认该数据段丢失。
- 关键参数:
- RTO:重传超时时间,其计算依赖于 RTT,TCP 会动态测量 RTT,并计算一个平滑的 RTT 值和偏差,以自适应地调整 RTO 值。
- 优点:简单,能处理任何原因的丢包(如拥塞、线路故障)。
- 缺点:反应较慢(通常需要等待一个 RTO 时间,RTO 往往 ≥ 200ms),效率低。
快速重传 —— 更积极的检测
为了解决超时重传的长时间等待问题,TCP 引入了快速重传。
- 原理:
- 接收方收到乱序的数据包时(比如收到了 5,但期望收到 3),会立即发送一个重复的 ACK(Dup ACK),ACK 号仍然是它所期望的下一个序列号。
- 发送方收到连续的三个重复的 ACK(即总共收到 4 个相同的 ACK,包括第一个正常的 ACK),就推断出该序列号对应的数据包已经丢失,而无需等待超时。
- 为什么是 3 次:1 或 2 次 Dup ACK 可能只是数据包乱序造成的“错误信号”,3 次是一个经验值,可以较好地平衡丢包误判和检测延迟。
- 优点:比超时重传快得多(通常在一个 RTT 内就能完成检测)。
- 缺点:依赖“连续” ACK,如果丢失的是窗口末尾的最后一个包或多个包,可能无法触发快速重传。
Forward ACK (FACK) —— 更精细的检测
FACK 是 Linux 内核采用的一种丢包检测算法,它利用 ACK 中的信息来更精确地定位丢失的包。
- 原理:
- 发送方维护两个关键变量:SND.NXT(待发送的下一个字节)和 SND.UNA(已确认的下一个字节)。
- 当收到一个 ACK 时,比较其 ACK 号与 SND.NXT,ACK 号小于 SND.NXT,说明有数据段未被确认。
- FACK 跟踪接收方已收到的最高序列号,通过计算已发送但未确认的字节数来判断丢包,当连续收到一定数量的重复 ACK 时,它就能更早地触发重传。
- 优点:在拥塞窗口较小或丢包模式复杂时,比标准的快速重传更敏锐、更准确。
Selective ACK (SACK)—— 高效处理连续丢包
标准 TCP 的 ACK 只能告知“期待的下一个序列号”,无法告诉发送方哪些包已经成功收到了,SACK 选项改变了这一点。
- 原理:
- TCP 选项字段中包含了 SACK 块,可以报告 1-4 个不连续的已经收到的数据块(收到 3-5 和 7-9,但缺失 6)。
- 发送方收到一个 Dup ACK(包含 SACK 信息)时,就能清楚知道哪些包已经到达(如 5 和 7 已到,但 6 丢失),从而仅重传丢失的包。
- 与快速重传的结合:发送方在收到 3 个 Dup ACK 并触发快速重传时,SACK 信息会告诉它要重传具体哪个包(比如包 6),而不是像标准 TCP 那样可能重传所有的未确认包。
- 优点:极大地提高了丢包重传效率,尤其在多个连续丢包时(如窗口中有 5 个包丢失,标准 TCP 可能需要多次 RTT 才能恢复,而 SACK 可以一次重组所有丢失的包)。
- 缺点:需要双方支持。
时间戳选项 —— 更精确的 RTT/RTO 计算
TCP 时间戳选项(RFC 1323)虽然不直接检测丢包,但为其他机制提供了基础。
- 原理:
- 每个数据包都携带一个时间戳。
- 接收方的 ACK 会回显这个时间戳。
- 发送方可以精确测量每个数据包的 RTT(而不是取平均),从而更准确地计算 RTO 值,避免不必要的超时。
- 意义:一个更准确的 RTO 可以减少“假超时”(即因为 RTO 设置过长而延迟丢包检测),也减少了“假重传”(RTO 过小导致误判)。
总结与对比
| 检测方式 | 触发条件 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 超时重传 | 重传计时器(RTO)到期 | 简单可靠,覆盖所有丢包 | 延迟高(RTO ~ 200ms+) | 所有丢失的兜底方案 |
| 快速重传 | 收到 3 个重复 ACK | 比超时快得多(~1 RTT) | 对单包丢失不敏感(依赖连续 ACK) | 单包或少量连续丢包 |
| FACK | 基于 ACK 号的精确窗口计算 | 更早、更准确地识别丢失 | 计算较复杂,依赖实现 | Linux 内核中性能较好 |
| SACK | 3 个 Dup ACK + SACK 信息 | 精确知道哪些包丢失,高效多包恢复 | 需要双方支持 | 高带宽、多丢包的场景 |
实际开发或排查中如何观察丢包?
- 系统层面(Linux):
netstat -s | grep -i "retrans":查看重传次数。ss -i:查看每个 TCP 连接的重传次数和 RTT。tcpdump:抓包后,观察重复 ACK 的数量和重传的数据包。
- 应用层面:
- 看到
TCP RTO或TCP Dup ACK的日志。 - 应用层观察到较高的延迟或连接超时。
- 看到
TCP 的丢包检测不是单一机制,而是多层级自适应系统:
- 首选:快速重传(基于 3 个 Dup ACK)+ SACK 精确定位,这是最快速、最经济的检测方式。
- 兜底:超时重传(基于 RTO),当快速重传失效(如尾部丢包、全局丢包)时,这是最后的保障。
- 协作:时间戳选项和 FACK 等机制,让 RTO 计算更准确,让检测更早发生。
理解这些机制,有助于你分析网络性能瓶颈(比如看到大量重传意味着链路质量差或拥塞),以及优化应用层代码(比如调整 Nagle 算法、窗口大小等)。
标签: TCP
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播