4. 抓包工具基础:Wireshark基础过滤、tcpdump命令行抓包
做UDP丢包分析,抓包是第一步。说白了,没有原始报文数据,后面所有理论都是空谈。我个人习惯是两手准备:图形界面用Wireshark,远程或服务器上用tcpdump。这两个工具配合好了,丢包问题基本无处遁形。
核心观点:抓包不是把网卡所有流量都录下来就完事了。精准抓包 + 有效过滤,才能从海量数据里快速定位丢包点。
4.1 Wireshark 基础过滤:从“看海”到“捞针”
Wireshark 打开一瞬间,满屏花花绿绿的报文。新手容易懵。我刚开始用的时候也这样,抓了10分钟,几万条记录,根本不知道看哪里。
后来我总结了一个原则:先粗后细,层层过滤。
4.1.1 捕获过滤器 vs 显示过滤器
这两个概念容易混淆。我简单解释一下:
| 类型 | 作用时机 | 语法 | 典型场景 |
|---|---|---|---|
| 捕获过滤器 | 抓包开始前设置,只抓符合条件的报文 | BPF(Berkeley Packet Filter) | 只抓特定IP或端口,减少磁盘写入 |
| 显示过滤器 | 抓包完成后,在已有数据中筛选 | Wireshark 专有语法(更强大) | 分析时只看UDP重传、只看特定载荷 |
我的建议:生产环境抓包,优先用捕获过滤器。我曾经在千兆链路上没加过滤直接抓全量,结果磁盘写爆,丢包分析还没开始就结束了。嗯,这个教训挺深刻的。
4.1.2 常用捕获过滤器(BPF语法)
BPF语法简洁,但写错了就抓不到东西。我列几个最常用的:
# 只抓UDP报文
udp
# 抓特定源IP的UDP
src host 192.168.1.100 and udp
# 抓特定端口(比如DNS)
udp port 53
# 抓一个网段
net 10.0.0.0/24
# 组合条件:源IP + 目标端口
src host 10.0.0.5 and dst port 12345
注意:捕获过滤器不支持“或”关系用 or 连接时,括号使用要小心。比如 udp and (port 53 or port 1234) 在部分旧版本tcpdump里会解析异常。我建议分开写,或者直接用显示过滤器。
4.1.3 显示过滤器:真正的大杀器
抓完包之后,显示过滤器才是分析主力。Wireshark 的过滤语法比 BPF 灵活得多。你想想看,它能直接解析协议字段,比如:
# 只看UDP报文
udp
# 只看特定端口
udp.port == 12345
# 只看特定IP之间的通信
ip.addr == 192.168.1.100 && udp.port == 12345
# 只看载荷长度大于100字节的UDP
udp.length > 100
# 只看UDP校验和错误的报文(丢包分析重点!)
udp.checksum_bad == 1
我个人最常用的是 udp.checksum_bad。为什么?因为很多UDP丢包其实是校验和错误导致的,网卡直接丢弃了,应用层根本不知道。这个过滤器能帮你快速揪出“沉默的凶手”。
4.2 tcpdump 命令行抓包:服务器上的瑞士军刀
生产服务器通常没有图形界面。这时候 tcpdump 就是唯一选择。我记得第一次在线上环境用 tcpdump,手都在抖——怕把业务抓挂了。后来用熟了才发现,只要参数给对,它比 Wireshark 还高效。
4.2.1 基础用法
# 最简单的抓包(默认抓第一个网卡)
tcpdump
# 指定网卡
tcpdump -i eth0
# 只抓UDP
tcpdump -i eth0 udp
# 抓100个包后自动停止
tcpdump -i eth0 -c 100
# 不解析域名(强烈建议加这个参数)
tcpdump -i eth0 -n udp
经验之谈:永远加上 -n 参数。不加的话,tcpdump 会反向解析每个IP的域名,DNS查询一来一回,抓包速度直接掉一个数量级。我曾经在高峰期忘了加,结果抓包进程自己成了网络瓶颈。
4.2.2 保存与读取
抓包文件是后续分析的原材料。保存格式要统一:
# 保存为pcap文件(Wireshark可直接打开)
tcpdump -i eth0 -w udp_capture.pcap
# 读取pcap文件
tcpdump -r udp_capture.pcap
# 读取时加过滤(不修改原文件)
tcpdump -r udp_capture.pcap udp port 12345
这里有个坑:-w 保存的是原始报文,不包含任何文本输出。如果你既想保存又想看实时输出,可以用 tee:
tcpdump -i eth0 -l | tee capture.log
4.2.3 高级过滤:精准定位丢包
丢包分析时,我经常需要同时看多个条件。tcpdump 的 BPF 语法虽然基础,但组合起来很强大:
# 抓特定源和目标
tcpdump -i eth0 src 10.0.0.1 and dst 10.0.0.2
# 抓特定端口范围
tcpdump -i eth0 udp portrange 10000-20000
# 抓特定载荷长度(丢包分析常用)
tcpdump -i eth0 'udp[7:2] > 100'
# 抓UDP校验和错误的包(需要网卡支持)
tcpdump -i eth0 'udp[6:2] & 0xffff != 0'
注意:最后一个校验和过滤,很多网卡硬件会直接丢弃校验错误的包,tcpdump 根本抓不到。这时候你需要关闭网卡的校验和卸载功能:ethtool -K eth0 rx off tx off。我踩过这个坑,排查了整整两天才发现是网卡“好心办坏事”。
4.3 本章知识体系
下面这张图总结了抓包工具的核心逻辑:
4.4 实战技巧:两个工具协同作战
我个人的工作流是这样的:
- 服务器端用 tcpdump 抓原始包,加
-n -s 0 -w参数,保存完整报文。 - 把 pcap 文件传到本地,用 Wireshark 打开。
- 先用显示过滤器粗筛,比如
udp.port == 12345。 - 再用高级过滤精确定位,比如
udp.checksum_bad == 1或udp.length > 1400。
你想想看,如果直接在服务器上用 tcpdump 分析,命令行输出密密麻麻,很难看出规律。但同样的数据在 Wireshark 里,图形化展示 + 颜色标记,丢包模式一目了然。
小技巧:Wireshark 支持 tcpdump 的过滤语法。你可以在 Wireshark 的“捕获选项”里直接粘贴 BPF 表达式。反过来,tcpdump 读取 pcap 文件时也可以加显示过滤。两个工具是互补的,不是对立的。
4.5 避坑指南
- 抓包时长控制:我曾经在高峰期抓了30分钟,生成了2GB的pcap文件。Wireshark打开直接卡死。建议每次抓包不超过5分钟,或者用
-c限制包数量。 - 网卡混杂模式:tcpdump 默认开启混杂模式,会抓取所有经过网卡的包。如果你只关心本机流量,加
-p参数关闭混杂模式,减少干扰。 - 时间戳精度:UDP丢包分析对时间敏感。tcpdump 默认微秒级精度,够用。但如果需要纳秒级,加
-tttt参数。 - 不要在生产环境长时间抓包:抓包本身有性能开销。我见过有人抓包把CPU吃满,业务直接挂掉。建议在测试环境复现问题,或者用
iptables做流量镜像。