用序号缺口找丢包
同一方向的数据报文序号连续递增,后一条的序号应该等于前一条的序号加上其载荷长度。如果出现跳跃,中间那段序号对应的数据就没有到达抓包点,这个空洞就是丢包位置。把两端抓包的缺口对照起来,就能判断丢包发生在哪一段路径上。需要注意的是,重传会把缺口补上,所以要看的是「首次出现缺口的帧」,而不是最终是否连续。
基本信息
| 计算规则 | 下一条序号应等于上一条序号加其载荷长度(next_seq = seq + len) |
|---|---|
| 缺口含义 | 下一条序号大于上一条的序号加长度,说明中间那段没到 |
| 过滤写法 | 配合显示过滤只保留某一方向且载荷大于零的数据帧 |
| 抓包位置 | 两端对照才能判断丢在哪段,单点只能证明缺口存在 |
| 注意事项 | 序号是相对值还是绝对值取决于抓包设置,分析时保持一致 |
典型使用场景
- 定位跨机房链路的丢包段:两端各抓一份,比对缺口出现位置
- 验证改动效果:变更前后比较单位时间内的缺口数量
- 区分丢包与乱序:缺口是否在后续被同一序号的帧补齐
- 排查大包丢失:结合载荷长度判断是否与分片相关
- 给运营商提供证据:缺口帧号与时间戳比口头描述有力得多
提取序号找缺口
提取序号找缺口
tcpdump -nn -i eth0 -s 96 -w /tmp/seq.pcap 'host 10.0.0.5 and tcp port 443'
# 提取方向、序号与长度:
tshark -r /tmp/seq.pcap -T fields -e frame.number -e ip.src -e tcp.seq -e tcp.len | head -40
# 只看某一方向的连续数据帧:
tshark -r /tmp/seq.pcap -Y 'ip.src == 10.0.0.5 && tcp.len > 0' -T fields -e frame.number -e tcp.seq -e tcp.len | sort -k2 -n | head
# 用 awk 直接算缺口(上一行 seq+len 与当前 seq 的差值):
tshark -r /tmp/seq.pcap -Y 'ip.src == 10.0.0.5 && tcp.len > 0' -T fields -e tcp.seq -e tcp.len | awk '{if (p && $1 > p) printf "gap %d bytes at seq %s\n", $1-p, $1; p=$1+$2}'结果判读
| 观察 | 含义 | 处置 |
|---|---|---|
| 序号严格连续 | 该方向无丢包 | 把排查方向转到对端或应用层 |
| 出现缺口且后续被补齐 | 发生丢包并触发重传 | 结合两端定位丢包段 |
| 出现缺口且有重复帧 | 丢包伴随乱序 | 先分离乱序,再看真实丢包 |
| 缺口集中在特定时间片 | 与突发或队列拥塞相关 | 检查中间设备队列与限速 |
| 两端缺口位置一致 | 丢在更上游或更下游 | 继续向两端扩展抓包点 |
有重传时缺口会被补上:要找的是首次出现缺口的帧,把首批空洞的帧号与两端抓包时间对齐,就能定位到具体那一段。