为什么用 Wireshark 分析 Modbus?
Wireshark 是全球最流行的开源网络协议分析器,由 Gerald Combs 于 1998 年创建,现由 Wireshark 基金会维护。官网 www.wireshark.org。它内置了完整的 Modbus TCP 协议解析器(dissector),可以自动识别和解析 Modbus TCP 报文中的 MBAP 头、功能码、数据区和异常码。对于 Modbus RTU 报文,Wireshark 也可以通过 USB 转串口适配器或远程抓包的方式进行分析。
在工业自动化的调试现场,最常见的痛点就是”通信不通但不知道为什么”。Wireshark 能让你看到总线上的每一帧数据——请求发了什么、响应回了什么、超时发生在哪个环节、异常码是什么——把看不见的通信过程变成可追踪的证据链。
Wireshark 对 Modbus 协议的支持
Wireshark 的 Modbus 协议解析器位于 epan/dissectors/packet-modbus.c,能够自动识别以下内容:
- Modbus/TCP:默认端口 502,自动识别 MBAP 头(Transaction ID、Protocol ID、Length、Unit ID)和各功能码的 PDU
- 功能码解析:FC01-FC06、FC15-FC16、FC23 等常用功能码的请求和响应格式
- 异常码:自动标注异常响应,并显示异常码含义(01=非法功能、02=非法数据地址、03=非法数据值、04=从站设备故障等)
- Modbus RTU over TCP:部分网关将 RTU 帧封装在 TCP 中传输,Wireshark 也能解析
安装 Wireshark
Linux(Ubuntu/Debian)
sudo apt-get update
sudo apt-get install wireshark
# 允许非 root 用户抓包
sudo usermod -a -G wireshark $USER
# 注销后重新登录生效
Windows
从 官网下载页面 下载 Windows 安装包。安装时需勾选 Npcap(Windows 抓包驱动)和 USBPcap(如需抓 USB 转串口数据)。
macOS
brew install --cask wireshark
抓取 Modbus TCP 报文
Linux 服务器端抓包
如果 Modbus TCP 通信发生在 Linux 服务器或网关上,直接用 tcpdump 抓包效率最高:
# 抓取所有目标端口为 502 的 TCP 报文(Modbus TCP 默认端口)
sudo tcpdump -i eth0 -w modbus_capture.pcap 'tcp port 502'
# 只抓指定 IP 设备的通信
sudo tcpdump -i eth0 -w modbus_capture.pcap 'host 192.168.1.100 and tcp port 502'
# 按 Ctrl+C 停止抓包
# 将 .pcap 文件传输到有 Wireshark 的电脑上分析
Windows 端直接抓包
打开 Wireshark,选择与目标设备通信的网卡(如以太网卡或 Wi-Fi),在 Capture Filter 中输入 tcp port 502,点击开始抓包。此时运行你的 Modbus 主站程序(如 Modbus Poll),即可捕获到完整的 Modbus TCP 通信过程。
Modbus TCP 报文详解
在 Wireshark 中选中一条 Modbus TCP 报文,展开 “Modbus/TCP” 层。一个典型的读保持寄存器请求报文结构如下:
| 字段 | 字节数 | 示例值 | 说明 |
|---|---|---|---|
| Transaction ID | 2 | 0x0001 | 事务标识符,客户端自增,服务端原样返回 |
| Protocol ID | 2 | 0x0000 | 协议标识,Modbus 固定为 0 |
| Length | 2 | 0x0006 | 后续字节数(Unit ID + PDU) |
| Unit ID | 1 | 0x01 | 从站地址(Slave ID) |
| Function Code | 1 | 0x03 | 功能码(03=读保持寄存器) |
| Starting Address | 2 | 0x0000 | 起始寄存器地址 |
| Quantity | 2 | 0x000A | 读取数量(10个) |
对应的响应报文包含同样的 MBAP 头 + 功能码 0x03 + 字节计数 0x14(20字节=10个寄存器)+ 数据区。
Wireshark 显示过滤器技巧
显示过滤器(Display Filter)用于在已抓取的报文中快速筛选目标数据。以下是常用的 Modbus 相关过滤器:
# 筛选所有 Modbus 协议报文
modbus
# 筛选指定功能码(如 03 读保持寄存器)
modbus.func_code == 3
# 筛选异常响应
modbus.exception_code
# 筛选指定从站地址
modbus.unit_id == 1
# 筛选包含异常的报文
modbus.exception_code != 0
# 组合过滤:从站 1 的功能码 16(写多寄存器)
modbus.unit_id == 1 and modbus.func_code == 16
# 按 IP 地址和 Modbus 功能码过滤
ip.addr == 192.168.1.100 and modbus.func_code == 3
# 只看 MBAP 头 Transaction ID 为 5 的请求-响应对
modbus.trans_id == 5
实战案例:用 Wireshark 排查 Modbus 通信故障
案例1:读不到数据——从站无响应
抓包后发现只有请求帧没有响应帧(或出现 TCP RST/重传),说明从站设备没有正确响应。检查方法:
- 确认 TCP 端口(默认 502)在从站设备上已开放
- 检查从站地址(Unit ID)是否与请求中的一致
- 查看是否有 TCP 层异常(重传、RST),如有则说明网络层有问题
案例2:返回异常码 02(非法数据地址)
Wireshark 可以看到请求中的起始地址 + 数量超出了从站的寄存器范围。在 Wireshark 中右键点请求报文 → “Follow → TCP Stream”,可以看到完整的请求和异常响应对话。
案例3:数据值异常——字节序问题
读取到的 32 位浮点数在 Wireshark 中显示正常,但在主站程序中显示为 NaN 或极大值。这说明通信层没问题,是主站程序的字节序解析有误。可以在 Wireshark 中手动计算验证:右键寄存器数据 → “Copy → Value” 获取十六进制原始值,用 IEEE 754 计算器在线验证。
抓取 Modbus RTU(串口)报文
Modbus RTU 通过 RS-232 或 RS-485 物理层传输,不能直接用 Wireshark 抓取。常见方案:
方案1:USB 转串口 + USBPcap
在 Windows 上安装 USBPcap(Wireshark 安装时可选组件),可以抓取 USB 转串口设备上的原始数据。但需要自行解析 RTU 帧(地址 + 功能码 + 数据 + CRC)。
方案2:串口监控软件
推荐使用专门的串口监控工具:
- Serial Port Monitor(Windows 商业软件):可直接监控和解析 Modbus RTU 帧
- CAS Modbus RTU Parser:免费在线工具,粘贴十六进制字节自动解析
- PortMon(Windows 免费):微软出品的底层串口监控工具
方案3:在 RTU 转 TCP 网关上抓包
如果现场使用了串口服务器(如 MOXA NPort),可以在 TCP 侧用 Wireshark 抓包,报文内容即为 RTU 帧。
Wireshark Modbus 分析进阶技巧
统计分析:I/O 图表
菜单 → Statistics → I/O Graph,设置过滤器为 modbus,可以观察到 Modbus 通信的频率和时间分布。如果发现周期性尖峰或间隙,可能是轮询参数配置不当。
查看完整的 TCP 流
右键任意 Modbus TCP 报文 → Follow → TCP Stream,可以查看一次完整 TCP 连接中所有 Modbus 请求和响应的原始数据。这是排查”读取数据错位”问题的利器。
导出 Modbus 数据
File → Export Packet Dissections → As CSV,可以将所有解码后的 Modbus 报文导出为 CSV 格式,方便用 Excel 或 Python 进行批量分析。
总结
Wireshark 是 Modbus 协议调试中不可替代的工具。它能够将”看不见”的通信过程可视化,帮助工程师精准定位问题发生在协议栈的哪一层——是 TCP 连接建立失败、MBAP 头字段错误、功能码不匹配、寄存器地址越界还是数据字节序解析错误。对于任何从事 Modbus 通信开发和调试的工程师,掌握 Wireshark 抓包分析是必备技能。
发表回复