news 2026/4/16 12:36:02

ModbusTCP协议抓包解析:Wireshark过滤技巧详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ModbusTCP协议抓包解析:Wireshark过滤技巧详解

从抓包开始,真正看懂 ModbusTCP 通信

你有没有遇到过这样的场景:上位机突然报“PLC离线”,可现场一看——电源正常、运行灯闪烁、程序也在跑。重启?没用。换网线?还是不行。最后只能一句“网络不稳定”草草收场。

其实问题很可能出在ModbusTCP 的底层通信细节上。而要真正看清这些问题,光靠日志和指示灯远远不够。你需要的是一双能“透视”网络流量的眼睛——比如Wireshark

本文不讲理论堆砌,也不罗列协议手册。我们直接从一次真实的抓包出发,带你一步步拆解 ModbusTCP 报文结构,掌握 Wireshark 中那些能让排查效率翻倍的过滤技巧,并用两个真实案例告诉你:为什么说“会抓包”的工程师,永远不怕背锅。


为什么是 ModbusTCP?它真的那么简单吗?

很多人觉得 ModbusTCP “简单到不需要学”——主站发个读寄存器命令,从站回个数据,完事。但正是这种“简单”,掩盖了潜在的风险。

ModbusTCP 其实是传统 Modbus 协议嫁接在 TCP/IP 栈上的产物。它保留了原有的功能码体系(如 FC03 读保持寄存器),但把原本串口上的 CRC 校验甩给了 TCP 层处理。听起来很合理,对吧?可一旦网络出现微小抖动、设备响应延迟或地址配置偏差,问题就会浮出水面。

更关键的是:ModbusTCP 没有加密、没有认证、也没有重传机制。如果一个请求丢了,或者响应慢了几百毫秒,主站通常只会默默超时,然后继续下一轮轮询。没人知道这一帧到底发生了什么。

这时候,你就需要打开 Wireshark,亲眼看看那条消失的数据包去了哪里。


一帧 ModbusTCP 报文长什么样?

先来看一个最典型的例子:上位机读取 PLC 的保持寄存器(FC03)。你在软件里设置了一下起始地址和数量,点击“测试连接”。背后实际发送的是这样一串十六进制数据:

0001 0000 0006 01 03 0064 0002

别慌,我们来一层层剥开它的结构。

MBAP 头部:Modbus 的“身份证”

前 6 字节叫做MBAP Header(Modbus Application Protocol Header),它是 ModbusTCP 区别于 RTU 的标志:

字段说明
Transaction ID (2B)0001事务标识符,用于匹配请求与响应
Protocol ID (2B)0000固定为 0,表示这是标准 Modbus
Length (2B)0006后续内容长度(Unit ID + PDU)
Unit ID (1B)01逻辑从站地址(常用于网关)

这 7 个字节就是 ModbusTCP 的外衣。去掉它,剩下的才是真正的 Modbus 协议数据单元(PDU):

03 0064 0002
  • 03:功能码 FC03,表示“读保持寄存器”
  • 0064:起始地址(十进制 100)
  • 0002:读取 2 个寄存器

整个报文总共12 字节,轻量得惊人。但也正因如此,任何一位写错、地址越界、设备忙,都可能导致异常响应甚至无响应。


Wireshark 是怎么“读懂”这些数据的?

当你在 Wireshark 里监听端口 502 的流量时,它并不会傻乎乎地把所有 TCP 流都当成 Modbus。它是靠端口号 + 协议解析器自动识别的。

只要目标或源端口是 502,Wireshark 就会尝试用内置的 Modbus 解析器去解码 payload。于是你看到的不再是乱糟糟的 HEX 数据,而是清晰的结构化字段:

Transaction ID: 1 Protocol ID: 0 Length: 6 Unit ID: 1 Function Code: Read Holding Registers (3) Starting Address: 100 Quantity: 2

而且,Wireshark 还能自动将一对请求和响应关联起来——只要它们的 Transaction ID 相同。你可以右键任一请求包 →Follow → TCP Stream,立刻看到完整的交互过程,连时间戳都给你标好了。

这才是真正的“所见即所得”。


高效抓包的关键:过滤器不是越多越好

很多人一开始抓包就全选接口、不限条件,结果几分钟下来几万条记录,根本没法分析。正确的做法是:层层缩小范围

第一步:捕获过滤器(Capture Filter)

在开始抓包前就设定规则,只让感兴趣的流量进来。语法基于tcpdump,运行在内核层,性能损耗极低。

常见写法:

tcp port 502

只抓 502 端口的 TCP 流量

tcp port 502 and host 192.168.1.10

只抓与特定设备(IP: 192.168.1.10)之间的 Modbus 通信

tcp port 502 and net 192.168.1.0/24

抓整个子网内的 Modbus 流量

⚠️ 注意:捕获过滤器一旦设错,漏掉的包再也找不回来。所以建议初期放宽条件,后期再用显示过滤器精筛。

第二步:显示过滤器(Display Filter)

抓完之后,用显示过滤器进一步筛选。这才是日常调试中最常用的工具。

实用过滤表达式合集:
目标显示过滤器
所有 Modbus 流量modbus
仅 FC03 请求(读保持寄存器)modbus.func_code == 3
所有异常响应modbus.func_code > 128
特定事务 ID 的完整交互modbus.trans_id == 1001
某个从站的所有通信modbus.unit_id == 1
写操作(FC16)modbus.func_code == 16

特别提醒:异常功能码 = 正常功能码 + 128
例如:
- 正常 FC03 →0x03
- 异常 FC03 →0x83(即 131)

所以查找所有异常响应,只需一条:

modbus.func_code > 128

你会发现很多本以为“成功”的操作,其实早已悄悄返回了0x82(非法数据地址)或0x84(从站设备忙)。


真实案例一:设备“假死”,其实是单向通信被拦了

故障现象

SCADA 系统频繁报警:“192.168.1.20 设备无响应”。但现场检查发现 PLC 运行正常,断电重启后短暂恢复,几分钟后又“失联”。

抓包分析

我们在 SCADA 侧启动 Wireshark,使用捕获过滤器:

tcp port 502 and dst host 192.168.1.20

观察结果:
- 请求包连续发出(Transaction ID 递增)
-没有任何来自 192.168.1.20 的响应包

看起来像是设备没回。但我们换个角度再看:

tcp port 502 and src host 192.168.1.20

这次更诡异了:连一个 outgoing 的 Modbus 响应都没有!

TCP 层呢?有没有 RST 或 FIN?
- 没有断开连接
- TCP 握手正常
- 主站持续发送数据,但从站零回应

最终定位:交换机 VLAN 配置错误,导致该设备所在端口无法向外转发数据包。设备“活着”,但消息发不出来。

💡 结论:不是设备坏了,也不是程序有问题,而是网络策略卡住了出口流量。没有抓包,这个问题可能永远查不到根上。


真实案例二:明明写了值,怎么读回来是错的?

故障现象

HMI 向 PLC 写入某个设定值(FC16),界面显示“写入成功”。但后续读取时发现数值不对,重启后又恢复正常。

抓包验证

我们加上显示过滤器:

modbus.func_code == 16

查看某次写入操作详情:
- 起始地址:400100
- 写入数量:1 个寄存器
- 数据值:0x1234

一切看似正常。但注意看响应包:

Function Code: 144 (Write Multiple Registers - Exception) Exception Code: 02 (Illegal Data Address)

原来!响应已经明确告诉主站:“你写的地址非法”

但主站软件却显示“写入成功”——因为它只判断是否有响应,根本不解析异常码。

根本原因

查阅 PLC 手册才发现:可用寄存器范围是400001 ~ 400099,而 HMI 配置中偏移量多加了 1,导致实际访问400100,越界!

🔧 解决方案:修正 HMI 工程中的地址映射表,避免硬编码偏移。

💡 教训:不要相信“看起来成功”的操作。一定要看响应内容,尤其是异常码。


工程师必备的几个调试秘籍

1. 如何快速确认两台设备是否互通?

telnet 192.168.1.10 502

能通不代表 Modbus 可用,但不通一定有问题。这是第一道筛查关。

2. 怎么判断是不是网络延迟导致超时?

在 Wireshark 中右键请求包 →Follow → TCP Stream,观察请求与响应之间的时间差。超过 200ms 就要警惕了。

3. 抓包文件太大怎么办?

  • 设置环形缓冲:抓满 100MB 自动覆盖旧数据
  • 使用触发保存:当检测到异常码时自动另存
  • 提前定义显示过滤器,避免无效记录

4. 安全注意事项

ModbusTCP 明文传输,敏感参数(如密码、校准系数)可能被窃听。务必做到:
- 抓包仅限调试环境
- 抓包完成后立即停止监听
- 敏感数据脱敏后再分享给他人


写在最后:掌握抓包,你就掌握了话语权

在这个越来越复杂的工业网络时代,会看协议的人,才有资格定义问题

当你能在会议室里拿出一份清晰的 Wireshark 截图,指着那一行Exception Code: 02说:“不是设备故障,是我们地址配错了”,那一刻,你就不再是被动等待修复的执行者,而是掌控全局的技术主导者。

也许未来 OPC UA、MQTT 会逐步替代 ModbusTCP,但在今天,仍有成千上万的产线依赖着这个“古老”却可靠的协议。而无论协议如何演进,深入底层、直面数据的思维方式永远不会过时。

下次再遇到“通信异常”,别急着重启。打开 Wireshark,按下开始,让数据自己说话。

如果你在实际项目中也遇到过棘手的 Modbus 问题,欢迎留言分享。我们一起拆解,把每一个“玄学”变成“科学”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 9:28:51

基于Vue2的v-scale-screen适配方案深度剖析

大屏适配的“隐形放大镜”:如何用 Vue2 指令实现设计稿级精准还原?你有没有遇到过这样的场景?项目验收现场,设计师精心打磨的 19201080 数据大屏,在客户那块拼接而成的 57601080 超宽屏幕上一打开——左边空出一大片黑…

作者头像 李华
网站建设 2026/4/10 16:19:19

基于OpenMV的实时人脸识别完整指南

从零开始,用 OpenMV 打造实时人脸识别系统 你有没有想过,一块比手掌还小的开发板,能独立完成人脸识别?不需要连接电脑、不依赖云端服务器——它自己就能“看”到人脸,并告诉你:“这是 Alice” 或 “陌生人…

作者头像 李华
网站建设 2026/4/13 15:41:35

Dify如何实现会话状态持久化?用户历史记录存储机制

Dify 如何让 AI “记住”用户?揭秘会话状态与历史记录的底层机制 在今天,一个真正“聪明”的 AI 助手,不该是每次对话都从零开始的“金鱼脑”。当你前脚问完订单编号,后脚再追问“那我上周买的呢?”,它却一…

作者头像 李华
网站建设 2026/4/12 18:39:49

nmodbus零基础教程:一步步实现寄存器读取

从零开始用 nmodbus 读取 Modbus 寄存器:实战入门全指南 你有没有遇到过这样的场景? 手头有一台支持 Modbus 协议的温控仪、PLC 或电表,想把它接入上位机系统,但面对“功能码”、“保持寄存器”、“字节序”这些术语一头雾水。手…

作者头像 李华
网站建设 2026/4/15 10:45:14

Blender3mfFormat插件终极指南:掌握3MF格式的完整工作流

Blender3mfFormat插件终极指南:掌握3MF格式的完整工作流 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 你是否在寻找将Blender打造成专业3D打印设计平台的方…

作者头像 李华
网站建设 2026/4/16 8:59:47

Dify平台API接口文档解读:实现外部系统无缝对接

Dify平台API接口解读:实现外部系统无缝对接 在企业智能化转型的浪潮中,越来越多团队希望将大语言模型(LLM)能力快速融入现有业务系统。然而,直接调用底层模型不仅门槛高,还面临提示工程复杂、上下文管理困…

作者头像 李华