TCP 流分析82 条

TCP ACK 号判读

ACK 号 = 期望接收的下一个字节序号:等于对端 seq+载荷长度;对照相邻包可确认"哪些数据已被确认"与"卡在哪个字节"。

确认号在说什么

确认号表示「期望收到的下一个字节序号」,等于对端已确认数据的序列号加上它的长度。例如收到序列号为 1、长度 100 的报文,回过来的确认号应当是 101,说明前 100 个字节已经收到。反复看到同一个确认号,说明在这个位置之后的数据一直没有到达,这正是丢包与乱序的共同特征。用它可以把「数据卡在哪个字节」直接算出来,比笼统地说「有重传」精确得多。

基本信息

规则本端发 [序列号, 序列号加长度),对端回确认号等于序列号加长度
判断缺口确认号长时间不推进即存在缺口
重复确认同一确认号反复出现,通常源于乱序或丢包
相对显示分析工具默认显示相对序列号,核对真实取值需切换为绝对值
配套字段载荷长度、窗口大小与标志位

典型使用场景

  • 确认数据是否送达:用确认号对应关系核对每一段数据
  • 定位卡住的字节位置:确认号停滞处就是缺口起点
  • 判断是否真的丢包:确认号不推进且伴随重复确认
  • 核对重传有效性:补发之后确认号是否立刻前移
  • 区分窗口问题与丢包:窗口为零时确认号不动但并非丢失

核对示例

核对示例
报文一:序列号 1,长度 100       对端确认号 101       已收到前 100 字节
报文二:序列号 101,长度 200     对端确认号 301       继续正常推进
重复出现确认号 301                                   说明 301 之后的数据没到
补发序列号 301 之后                                     确认号开始前移,缺口恢复

确认号与相关字段

字段含义判读要点
确认号期望收到的下一个字节长时间不变说明数据没有到达对端
序列号本段数据的起始字节与长度一起决定对端应回的确认号
载荷长度本段的字节数为零时确认号不应推进
窗口大小对端可接收的剩余空间为零时确认号不动属于流量控制而非丢包
重复确认同一确认号多次出现三个以上通常触发快速重传
分析工具默认显示相对序列号,便于阅读但不利于核对真实取值。需要与对端记录或日志比对时,先切换为绝对序号显示,避免把相对值当成真实值。
确认号不动不一定意味着丢包:接收方窗口为零时同样不会推进。看到不动要先看窗口字段,再看重复确认的数量,才能区分流量控制与数据丢失。

结合统计核对

结合统计核对
tshark -r a.pcap -Y 'tcp.stream==7' -T fields -e tcp.seq -e tcp.len -e tcp.ack -e tcp.window | head -20
ss -ti | grep -A1 ':443'      # 套接字层面的确认与重传统计

判读要点

  • 确认号严格按字节推进,出现跳跃说明中间有未被确认的数据或存在乱序
  • 同一确认号反复出现时先数次数,达到三次以上通常伴随快速重传
  • 确认号推进变慢但从未停滞,说明链路有丢包但恢复机制在工作
  • 抓包点丢包会造成确认号看似跳空,结论前先确认抓包本身是否完整

易错点

  • 把确认号不动直接当作丢包,忽略了接收窗口为零的流量控制情形
  • 用相对序号显示的数值与对端记录比对,得到对不上的结论
  • 只看确认号不看载荷长度,无法判断该段是否真的携带数据
  • 抓包点丢包导致确认号看似跳跃,未确认抓包完整性就下结论
  • 把确认号停滞当成应用问题,忽略了传输层缺口需要先恢复才能推进

数据来源与参考

  • RFC 9293(序号与确认)
  • Wireshark User's Guide
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌