3. 抓包工具入门:tcpdump基础用法、Wireshark基础用法、如何抓取超时相关的包

说到排查连接超时,我最先想到的工具就是抓包。你想想看,网络问题说白了就是包丢了、包慢了、包错了。没有抓包数据,你就是在黑暗中摸索。我个人习惯是:先tcpdump留证据,再Wireshark慢慢分析。这一章我们就来搞定这两把刀。

核心原则:抓包不是为了看热闹,而是为了还原“那一刻网络到底发生了什么”。超时场景下,我们要重点看:SYN是否发出、SYN-ACK是否回来、谁发了RST、重传间隔是否异常。

3.1 tcpdump:命令行下的网络显微镜

tcpdump是Linux环境下的标配。我刚开始用的时候也记不住参数,后来总结了一套“三板斧”,够用了。

3.1.1 基础语法

# 最简抓包:抓eth0网卡所有流量
tcpdump -i eth0

# 指定端口和协议,避免被海量数据淹没
tcpdump -i eth0 tcp port 80

# 保存到文件,方便后续分析
tcpdump -i eth0 -w capture.pcap

# 读取pcap文件
tcpdump -r capture.pcap

嗯,这里要注意:-w 保存的是二进制文件,别用cat看,会乱码。用 -r 读回来。

3.1.2 超时场景必用参数

参数 作用 超时排查中的用法
-n 不解析域名 避免DNS查询拖慢抓包,直接显示IP
-v 显示详细信息 看TTL、窗口大小、时间戳
-S 显示绝对序列号 对比重传时序列号是否一致
tcp[tcpflags] 过滤特定标志位 只抓SYN、RST、FIN包

我的习惯:抓超时问题时,我一般这样组合:tcpdump -i eth0 -n -S tcp port 8080 -w timeout.pcap。既保留原始信息,又避免域名解析干扰。

3.1.3 过滤表达式实战

抓包最怕的是数据太多。你需要学会“精准打击”。

# 只抓SYN包(三次握手第一步)
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'

# 只抓RST包(连接被重置)
tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0'

# 抓从客户端到服务器的包
tcpdump -i eth0 src host 192.168.1.100 and dst port 443

# 抓重传包(序列号相同)
tcpdump -i eth0 'tcp[4:2] == 0'  # 简化版,实际需要结合窗口

我曾经在排查一个“间歇性超时”问题时,就是靠 tcpdump 'tcp[tcpflags] & tcp-rst != 0' 抓到了对端主动发的RST包,才发现是防火墙策略过期了。没有这个过滤,你会在几千个包里翻到崩溃。

3.2 Wireshark:图形化的协议解码器

tcpdump负责“采集”,Wireshark负责“分析”。我个人觉得Wireshark最大的价值在于:它帮你把二进制流翻译成了人能看懂的语言。

3.2.1 打开pcap文件

把tcpdump抓的 .pcap 文件拖进Wireshark就行。或者用命令行:

wireshark -r timeout.pcap

3.2.2 超时排查必用的Wireshark功能

  • Follow TCP Stream:右键一个TCP包 → Follow → TCP Stream。能还原整个会话的对话内容,一眼看出哪一步卡住了。
  • Expert Info:Analyze → Expert Info。Wireshark会自动标记异常:重传、重复ACK、零窗口等。超时场景下,这里会有一堆红色/黄色警告。
  • Time列:默认显示的是相对时间。我建议改成“Seconds Since Beginning of Capture”,方便看每个包的时间间隔。

避坑指南:我曾经在分析一个慢连接问题时,盯着Wireshark看了半小时没发现问题。后来才发现,我忘了开启“Allow subdissector to reassemble TCP streams”。导致HTTP请求被切成了好几段,根本看不出完整延迟。记得在 Edit → Preferences → Protocols → TCP 里勾上这个选项。

3.2.3 过滤语法(Display Filter)

Wireshark的过滤语法比tcpdump更直观。我常用的几个:

过滤表达式 含义
tcp.analysis.retransmission 显示所有重传包
tcp.analysis.fast_retransmission 快速重传(通常意味着丢包)
tcp.analysis.zero_window 接收端窗口为0(对方处理不过来)
tcp.flags.reset == 1 所有RST包
tcp.time_delta > 1 包间隔超过1秒(超时嫌疑)

3.3 如何抓取超时相关的包

理论说完了,我们来点实战。假设你的应用报“连接超时”,你怎么抓包?

3.3.1 抓包时机:提前启动 vs 事后分析

超时问题分两种:持续超时和间歇超时。

  • 持续超时:每次都超时。好办,直接启动抓包,然后发起一次请求,看完整交互。
  • 间歇超时:偶尔超时。这个麻烦。我建议用 tcpdump -G 60 -W 10 按分钟轮转保存,每个文件1分钟,保留10个文件。等超时复现后,看对应时间段的文件。
# 轮转抓包:每60秒生成一个新文件,最多保留10个
tcpdump -i eth0 -G 60 -W 10 -w timeout_%Y%m%d_%H%M%S.pcap tcp port 443

3.3.2 超时场景的抓包策略

超时类型 抓包策略 重点关注
连接建立超时 抓客户端到服务端SYN包 SYN是否发出?SYN-ACK是否回来?
数据传输超时 抓双向流量 是否有重传?窗口是否为零?
连接关闭超时 抓FIN/ACK交互 FIN是否被对端确认?TIME_WAIT是否堆积?

我的经验:抓连接建立超时,我一般会在客户端和服务端同时抓包。客户端抓到的SYN如果没收到SYN-ACK,可能是中间设备丢了包;服务端如果没收到SYN,那就是网络问题。两边一对比,问题在哪一段就清楚了。

3.3.3 实战案例:抓一个“连接超时”

假设客户端IP是 10.0.0.1,服务端IP是 10.0.0.2,端口 8080。

步骤1:在客户端启动抓包

tcpdump -i eth0 -n -S host 10.0.0.2 and port 8080 -w client.pcap

步骤2:复现超时

发起请求,等待超时。

步骤3:停止抓包,用Wireshark分析

打开 client.pcap,使用过滤 tcp.analysis.retransmission。你会看到类似这样的场景:

  • 第1个包:客户端发SYN
  • 第3秒:客户端重传SYN(第一次超时重传)
  • 第6秒:客户端重传SYN(第二次)
  • 第12秒:客户端重传SYN(第三次)
  • 第24秒:客户端放弃,返回超时

这说明服务端根本没回SYN-ACK。要么服务端挂了,要么中间防火墙把SYN丢了。

3.4 本章知识体系

下面这张图总结了抓包工具在超时排查中的定位和流程。

抓包工具超时排查知识体系 抓包工具超时排查知识体系 连接超时场景 tcpdump(采集) Wireshark(分析) tcpdump核心用法 -i 指定网卡 / -w 保存文件 -n 不解析域名 / -S 绝对序列号 过滤表达式:tcpflags / src host Wireshark核心用法 Follow TCP Stream 还原会话 Expert Info 自动标记异常 显示过滤:retransmission / zero_window 定位超时根因

3.5 本章小结

抓包是网络排查的“眼睛”。tcpdump负责在问题发生时留下现场证据,Wireshark负责把证据翻译成我们能理解的时序图。超时场景下,你只需要记住三件事:

  1. 抓什么:SYN、RST、重传包、窗口更新包
  2. 怎么抓:持续超时直接抓,间歇超时轮转抓
  3. 怎么看:Follow Stream看对话,Expert Info看异常,Time列看间隔