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 本章知识体系

下面这张图总结了抓包工具的核心逻辑:

抓包工具核心知识体系 Wireshark(图形界面) tcpdump(命令行) 捕获过滤器(BPF语法) 显示过滤器(Wireshark语法) IP/端口过滤 协议/载荷过滤 校验和过滤 文件保存/读取 精准定位丢包点 ⚠ 避坑:关闭网卡校验和卸载、加 -n 参数、控制抓包时长

4.4 实战技巧:两个工具协同作战

我个人的工作流是这样的:

  1. 服务器端用 tcpdump 抓原始包,加 -n -s 0 -w 参数,保存完整报文。
  2. 把 pcap 文件传到本地,用 Wireshark 打开。
  3. 先用显示过滤器粗筛,比如 udp.port == 12345。
  4. 再用高级过滤精确定位,比如 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 做流量镜像。