Wireshark 使用指南:Linux 下用 tcpdump 抓包并分析 Modbus 报文
目标
本文档用于指导在 Linux 环境下完成以下工作:
- 使用
tcpdump抓取 Modbus TCP 通信报文 - 使用 Wireshark 对抓到的
.pcap或.pcapng文件进行分析 - 通过一个完整的 Modbus 读寄存器示例,掌握请求与响应的拆解方法
- 快速定位通信失败、超时、异常码、地址错误、寄存器数量错误等问题
本文重点面向 Modbus TCP 场景,即通过 TCP 端口 502 进行通信的情况。
适用场景
以下情况都适合使用本文档的方法:
- EMS 与 PLC、PCS、BMS、电表、保护装置之间的 Modbus TCP 联调
- 现场设备“能连通但读不到数据”的问题排查
- 核对主站下发的寄存器地址、功能码、寄存器数量是否正确
- 分析从站返回异常码的具体原因
- 复盘偶发超时、重传、断链、错误响应等网络问题
环境准备
建议准备以下工具:
- Linux 主机一台
tcpdump- Wireshark
- 被抓包的 Modbus TCP 通信链路
- 具备
sudo权限的账号
Ubuntu / Debian 可参考:
sudo apt-get update
sudo apt-get install -y tcpdump wireshark
安装完成后可确认版本:
tcpdump --version
wireshark --version
如果当前用户无权限直接打开抓包文件或使用抓包能力,可临时通过 sudo 执行抓包命令。
整体流程
整个操作流程建议按下面顺序执行:
- 确认通信网卡、对端 IP、TCP 端口
- 使用
tcpdump抓取 Modbus TCP 报文到文件 - 用 Wireshark 打开抓包文件
- 使用显示过滤器筛选目标流量
- 对照 Modbus 报文字段逐项分析
- 根据现象判断是网络问题、协议问题还是业务配置问题
步骤一:确认抓包对象
抓包前,先确认以下信息:
- 本机使用的是哪块网卡
- Modbus 对端 IP 是多少
- 是否确实走 TCP 端口
502 - 抓包点位于主站侧、从站侧,还是中间交换网络
1. 查看本机网卡
ip -br addr

如果机器有多张网卡,务必确认哪块网卡承载了现场业务流量。
2. 查看抓包接口列表
sudo tcpdump -D

输出中通常会列出类似 eth0、ens33、enp3s0、bond0、any 等接口名称。
3. 确认 Modbus 连接是否存在
ss -ant | grep ':502'
如果已经建立连接,通常能看到:
- 客户端临时端口 -> 服务端
502 ESTAB状态表示 TCP 已建立

步骤二:使用 tcpdump 抓取 Modbus TCP 报文
1. 最常用抓包命令
sudo tcpdump -i eth0 -nn -s 0 -w modbus_tcp.pcap 'tcp port 502'
参数说明:
-i eth0:指定抓包网卡,请替换为现场实际网卡-nn:不做主机名和端口名解析,避免输出被解析结果干扰-s 0:抓取完整报文,不截断-w modbus_tcp.pcap:将数据写入文件,供 Wireshark 打开'tcp port 502':只抓取 Modbus TCP 常用端口数据
2. 抓指定主机与端口
如果只想抓某个设备与本机之间的 Modbus 报文:
sudo tcpdump -i eth0 -nn -s 0 -w modbus_192.168.1.10.pcap 'host 192.168.1.10 and tcp port 502'
3. 抓双向通信并保留完整上下文
若现场可能存在建链失败、重传、RST、异常关闭等情况,建议抓整个会话,而不是只抓应用层片段:
sudo tcpdump -i eth0 -nn -s 0 -w modbus_full_session.pcap 'host 192.168.1.10'
这样在 Wireshark 中可以同时看到:
- TCP 三次握手
- Modbus 请求与响应
- 重传、乱序、RST、FIN
4. 长时间抓包建议
如果现场问题偶发,建议使用轮转文件,避免单文件过大:
sudo tcpdump -i eth0 -nn -s 0 -C 100 -W 10 -w modbus_ring.pcap 'tcp port 502'
参数说明:
-C 100:单个文件达到 100 MB 后切换-W 10:最多保留 10 个文件,循环覆盖
5. 抓包结束
抓包过程中按 Ctrl + C 停止。结束时 tcpdump 会输出抓到的数据包统计信息。
步骤三:使用 Wireshark 打开抓包文件
抓包完成后,启动 Wireshark 并打开文件:
wireshark modbus_tcp.pcap

也可以直接启动 Wireshark 后,通过图形界面打开抓包文件。
打开后,界面通常分为三部分:
- 数据包列表区:展示时间、源地址、目的地址、协议、长度、摘要信息
- 协议树详情区:逐层展开 Frame、Ethernet、IP、TCP、Modbus 等字段
- 字节区:展示原始十六进制内容,并高亮当前选中字段

步骤四:在 Wireshark 中过滤 Modbus 报文
Wireshark 分为两类过滤:
- 抓包过滤器:
tcpdump执行时使用,决定“抓什么” - 显示过滤器:Wireshark 中使用,决定“看什么”
本文主要关注 Wireshark 的显示过滤器。
1. 显示所有 Modbus 报文
modbus
如果 Wireshark 已正确识别协议,这个过滤器最直接。
2. 按 TCP 端口过滤
tcp.port == 502

3. 按 IP 地址过滤
ip.addr == 192.168.3.23

4. 只看某个方向
ip.src == 192.168.1.100 && ip.dst == 192.168.1.10 && tcp.port == 502

这个过滤器适合只看主站请求,或只看从站响应。
5. 只看异常与网络问题
tcp.analysis.retransmission
tcp.flags.reset == 1
modbus || tcp.analysis.retransmission || tcp.flags.reset == 1
6. 端口不是 502 时的处理方法
有些测试环境不会使用标准端口 502。如果 Wireshark 没有自动识别成 Modbus,可手动指定:
- 选中对应 TCP 报文
- 菜单进入
Analyze -> Decode As... - 在对应 TCP 端口上选择
Modbus/TCP - 应用后再使用
modbus过滤
步骤五:结合示例分析 Modbus 报文
下面用一个典型的 读取保持寄存器 示例说明如何分析。
示例场景
- 主站 IP:
192.168.1.100 - 从站 IP:
192.168.1.10 - TCP 端口:
502 - 单元标识符(Unit ID):
1 - 功能码:
0x03,读取保持寄存器 - 起始地址:
0x0000 - 读取数量:
1
1. 请求报文示例
十六进制内容如下:
00 21 00 00 00 06 01 03 00 00 00 01
拆解如下:
| 字节位置 | 字段 | 值 | 含义 |
|---|---|---|---|
| 0-1 | Transaction Identifier | 0x0021 |
事务标识,用于请求响应匹配 |
| 2-3 | Protocol Identifier | 0x0000 |
Modbus TCP 固定为 0 |
| 4-5 | Length | 0x0006 |
后续字节长度 |
| 6 | Unit Identifier | 0x01 |
设备地址 / 单元标识 |
| 7 | Function Code | 0x03 |
读取保持寄存器 |
| 8-9 | Starting Address | 0x0000 |
起始地址 |
| 10-11 | Quantity | 0x0001 |
读取 1 个寄存器 |
分析结论:
- 这是一个标准的 Modbus TCP 读保持寄存器请求
- 主站要求从地址
0开始读取连续1个寄存器 Transaction Identifier为1,后续响应通常会保持一致

2. 响应报文示例
十六进制内容如下:
00 21 00 00 00 05 01 03 02 70 f8
拆解如下:
| 字节位置 | 字段 | 值 | 含义 |
|---|---|---|---|
| 0-1 | Transaction Identifier | 0x0021 |
与请求匹配 |
| 2-3 | Protocol Identifier | 0x0000 |
固定为 0 |
| 4-5 | Length | 0x0005 |
后续字节长度 |
| 6 | Unit Identifier | 0x01 |
单元标识 |
| 7 | Function Code | 0x03 |
响应功能码,与请求一致 |
| 8 | Byte Count | 0x02 |
返回 4 个字节数据 |
| 9-10 | Register 0 | 0x0070 |
十进制 112 |
| 11-12 | Register 1 | 0x00f8 |
十进制 248 |
分析结论:
- 响应与请求事务号一致,说明配对正确
- 返回了 2 个寄存器,共
4字节,和请求数量一致 - 两个寄存器的值分别为
100和200

3. 如何在 Wireshark 中看懂这类报文
分析时建议按下面顺序看:
- 先看 TCP 层
- 是否成功三次握手
- 是否有重传、RST、乱序、零窗口
- 再看 MBAP 头
Transaction Identifier是否能和响应匹配Protocol Identifier是否为0Length是否合理Unit Identifier是否符合设备配置
- 最后看 Modbus PDU
- 功能码是否正确
- 起始地址是否正确
- 寄存器数量是否超限
- 返回字节数是否与寄存器数量一致
如果 Wireshark 协议树能正确展开,一般说明 TCP 层和 Modbus 报文结构至少基本可解析。
4. 异常响应示例
若从站不支持请求的功能、地址错误或数量越界,常见会返回异常响应。例如:
00 03 00 00 00 03 01 83 02
拆解如下:
| 字段 | 值 | 含义 |
|---|---|---|
| Transaction Identifier | 0x0003 |
与请求配对 |
| Unit Identifier | 0x01 |
单元标识 |
| Function Code | 0x83 |
异常响应,0x80 + 0x03 |
| Exception Code | 0x02 |
非法数据地址 |
说明:
- 正常功能码是
0x03 - 异常响应时功能码最高位置位,因此变成
0x83 0x02常表示寄存器地址不存在、越界,或设备不支持该地址范围
常见异常码
| 异常码 | 名称 | 常见原因 |
|---|---|---|
0x01 |
Illegal Function | 功能码不支持 |
0x02 |
Illegal Data Address | 地址错误、寄存器不存在、地址越界 |
0x03 |
Illegal Data Value | 数量、值或参数非法 |
0x04 |
Slave Device Failure | 从站内部处理失败 |
步骤六:定位常见问题
下面给出现场最常见的几类现象以及对应排查思路。
1. 看不到任何 Modbus 报文
排查方向:
- 抓错网卡
- 流量不经过当前主机
- 端口不是
502 - 防火墙或交换机策略限制
- 通信根本没有发起
建议操作:
sudo tcpdump -i any -nn -s 0 -w test_any.pcap host 192.168.1.10
先放宽过滤条件确认有没有相关主机流量,再逐步收窄。
2. 能看到 TCP 建链,但没有 Modbus 数据
排查方向:
- 应用程序连接成功但未发请求
- 上层程序卡住或等待条件未满足
- 使用了非 Modbus 协议
- 端口被复用,但协议不是 Modbus
建议在 Wireshark 中观察:
- TCP 三次握手之后是否出现
PSH, ACK - 载荷是否能被
Decode As Modbus/TCP
3. 有请求,无响应
排查方向:
- 从站未收到请求
- 从站收到但未处理
- 网络单向不通
- 中间设备丢包
- 从站处理超时
重点看:
- 请求发出后是否有 TCP 重传
- 是否有 ICMP 不可达
- 是否最终收到
RST
4. 响应是异常码
排查方向:
- 功能码不支持
- 寄存器地址写错
- 地址基准错位
- 读取数量超限
- 单元标识符配置错误
工业现场很常见的问题是:
- 文档地址从
40001开始描述,但程序里直接用了协议地址0 - 或者相反,设备要求协议地址,主站却把文档地址直接发下去了
因此要特别确认:
- 设备手册中的地址是 协议地址
- 还是 人类可读的数据模型地址
5. Wireshark 能解包,但数值不对
排查方向:
- 寄存器高低位组合方式不对
- 多寄存器拼接时字序不同
- 设备手册定义的是有符号数,程序按无符号解释
- 缩放比例未处理,例如真实值为“寄存器值 / 10”
这类问题通常不是网络故障,而是 协议解释或点表配置问题。
6. 报文正常,但业务仍报超时
排查方向:
- 应用层超时时间设置过短
- 程序在等待错误的事务号
- 多线程并发访问同一连接导致响应配对错乱
- 上层日志记录时间与抓包时间不一致
建议同时核对:
- 程序日志时间
- 抓包时间戳
Transaction Identifier- 同一 TCP 流中的请求响应顺序
推荐抓包命令模板
模板 1:标准 Modbus TCP 抓包
sudo tcpdump -i eth0 -nn -s 0 -w modbus_tcp.pcap 'tcp port 502'
模板 2:抓指定设备
sudo tcpdump -i eth0 -nn -s 0 -w modbus_device.pcap 'host 192.168.1.10 and tcp port 502'
模板 3:抓完整会话
sudo tcpdump -i eth0 -nn -s 0 -w modbus_full.pcap 'host 192.168.1.10'
模板 4:长时间轮转抓包
sudo tcpdump -i eth0 -nn -s 0 -C 100 -W 10 -w modbus_ring.pcap 'tcp port 502'
模板 5:先粗抓、后精看
sudo tcpdump -i any -nn -s 0 -w all_traffic.pcap host 192.168.1.10
适合一开始不确定端口、协议、网卡或方向时使用。
最佳实践
- 抓包时优先使用
-s 0,避免报文被截断 - 尽量抓到完整会话,包括 TCP 握手和断开过程
- 抓包文件命名建议包含设备 IP、时间、问题现象
- 问题偶发时优先使用轮转抓包
- 分析时先看网络层是否通,再看 Modbus 协议字段是否正确
- 不要只看“有没有响应”,还要核对响应是不是匹配的事务号
- 如果端口不是
502,记得在 Wireshark 中使用Decode As - 对照设备手册时,务必确认地址基准和数据类型定义
推荐命名格式:
modbus_192.168.1.10_2026-04-17_读寄存器超时.pcap
附录:常见 Modbus 功能码
| 功能码 | 名称 | 说明 |
|---|---|---|
0x01 |
Read Coils | 读线圈 |
0x02 |
Read Discrete Inputs | 读离散输入 |
0x03 |
Read Holding Registers | 读保持寄存器 |
0x04 |
Read Input Registers | 读输入寄存器 |
0x05 |
Write Single Coil | 写单个线圈 |
0x06 |
Write Single Register | 写单个寄存器 |
0x0F |
Write Multiple Coils | 写多个线圈 |
0x10 |
Write Multiple Registers | 写多个寄存器 |
总结
使用 tcpdump + Wireshark 分析 Modbus TCP 的核心思路可以概括为三句话:
- 先确认流量到底有没有到达
- 再确认 Modbus 报文字段到底是不是按协议发送
- 最后确认业务点位解释是否和设备手册一致
只要把 网卡、IP、端口、事务号、功能码、地址、数量、异常码 这几个关键点按顺序核对,绝大多数 Modbus TCP 问题都可以较快定位。
更多推荐




所有评论(0)