当前位置: 首页 > news >正文

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 问题,欢迎留言分享。我们一起拆解,把每一个“玄学”变成“科学”。

http://www.jsqmd.com/news/140629/

相关文章:

  • 工业抗干扰设计中的数字电路基础原理剖析
  • Elasticsearch教程:全面讲解分词器配置与应用场景
  • 全面讲解ollydbg下载及安装常见问题与解决方案
  • Dify如何实现对敏感内容的过滤与审核?合规性解析
  • ollydbg下载及安装基础配置:字体与界面设置技巧
  • Dify平台性能瓶颈分析:当前版本需注意的几个关键点
  • 零基础学习Artix-7开发——vivado安装教程2018
  • AI原生应用的可解释性:从LIME到SHAP的全面解析
  • 一文说清DMA存储器到外设传输工作原理
  • 从ADB到fastboot:驱动切换机制图解说明
  • 图解说明电路板PCB设计基本步骤(适合零基础)
  • 多线程竞争资源导致crash的通俗解释
  • 通过OpenMV实现农作物计数:快速理解方案
  • Dify平台主题与UI自定义能力:打造品牌专属界面
  • nmodbus零基础教程:一步步实现寄存器读取
  • DUT接口匹配技术详解:手把手教程(从零实现)
  • Dify平台能否替代传统后端开发?边界在哪里?
  • nanopb + MQTT 在嵌入式端的整合示例
  • Dify与Zapier类工具集成前景:无代码自动化再升级
  • Dify平台能否用于舆情监控?新闻聚合与情感分析实践
  • Dify与LangChain对比:谁更适合企业级AI应用开发?
  • 为工业4.0赋能:Vivado注册2035系统级设计全面讲解
  • 一文说清USB3.0主机控制器工作模式
  • Dify平台缓存机制详解:减少重复Token调用降低成本
  • Packet Tracer汉化全面讲解:支持语言包加载方法
  • 基于OpenMV的实时人脸识别完整指南
  • Dify平台社区活跃度分析:开源力量推动AI平民化
  • MicroPython与云平台通信项目应用实例
  • Dify在金融领域的应用尝试:自动化报告生成系统搭建
  • Dify + GPU集群:构建高并发AI服务的终极解决方案