首页/网络/抓包与流量分析速查/TCP SACK 选择性确认
TCP 流分析82 条

TCP SACK 选择性确认

SACK 让接收端告诉发送端"哪些块已收到",避免逐段重传;抓包中看 ACK 的 SACK 块(tcp.options.sack)即可了解缺口恢复进度。

SACK 是什么

SACK 让接收端在确认包里附带「我已经收到哪些不连续的块」,发送端据此只重传真正缺失的部分,避免把已经到达的数据再发一遍。它在握手阶段通过 SACK Permitted 选项协商启用,抓包时看确认报文里的 SACK 块数量与推进情况,就能判断丢包恢复的效率。

基本信息

标准依据RFC 2018 定义,RFC 6675 给出重传算法
协商方式握手中交换 SACK Permitted 选项
抓包字段tcp.options.sack_le 与 sack_re(Wireshark 解析)
核心作用只重传缺失块,减少无谓重传
配合字段tcp.analysis.duplicate_ack 与重传标注

典型使用场景

  • 高丢包链路上评估恢复效率:缺口是否被快速补上
  • 区分重复确认是乱序还是丢包:有 SACK 推进多为乱序
  • 核对中间设备是否篡改或丢弃了握手选项
  • 评估一次丢包对吞吐的实际影响
  • 对比启用与未启用选择性确认时的恢复速度

常用过滤

常用过滤
tcp.options.sack                                        # 带有 SACK 块的确认
tcp.options.sack_permitted && tcp.flags.syn == 1        # 握手协商情况
tcp.stream == N && tcp.options.sack                     # 指定会话的 SACK
tcp.options.sack && tcp.analysis.duplicate_ack          # 重复确认中的 SACK

观察项与含义

观察项含义说明
握手含 SACK Permitted双方支持选择性确认未协商则退化为逐段确认
确认携带 SACK 块接收端已收到的不连续块据此判断缺口位置
SACK 块逐步推进恢复正在进行缺口在被填上
SACK 块长时间不变恢复受阻检查丢包是否持续
SACK 描述的是接收缓冲中的不连续区域,解读时要与序列号一起看,不能只数块的数量。
中间设备丢弃或改写选项会破坏协商,怀疑时直接核对握手报文的选项列表。

补充要点

  • 把 SACK 与重复确认结合看,能判断接收端是缺一段还是收到乱序
  • 缺口长时间不被补齐时,问题可能在发送端的重传策略而不在接收端
  • 选择性确认不改变丢包发生的事实,只影响恢复速度
  • 长距离高丢包链路上,恢复速度对业务体验的影响往往比丢包率本身更大
统计 SACK 相关的恢复耗时可以用相邻两块推进之间的时间差近似,方法简单但需要人工核对。

易错点

  • 把带有 SACK 块当作丢包证据:乱序场景下接收端同样会给出 SACK
  • 在未协商成功时按 SACK 预期分析恢复效率,结论与实际机制不符
  • 只数 SACK 块数量不看位置,无法判断缺口是否真的在被填补

数据来源与参考

  • RFC 2018(SACK)
  • RFC 6675(SACK 重传算法)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌