4. Modbus TCP/IP 模式详解
各位工程师朋友,今天我们来聊聊 Modbus TCP/IP。说实话,这个协议在工业现场用得越来越多了。我最早接触它是在一个大型水处理项目上,当时甲方要求所有设备走以太网,我还在想:这玩意儿跟 RTU 到底有啥区别?后来踩了不少坑,才慢慢摸透了它的脾气。
4.1 TCP/IP 帧结构:MBAP 报文头 + 协议数据单元
Modbus TCP/IP 的帧结构,说白了就两部分:MBAP 报文头和协议数据单元(PDU)。你想想看,RTU 有 CRC 校验,ASCII 有 LRC 校验,TCP/IP 呢?它靠的是 TCP 协议本身的可靠性,所以 MBAP 头里没有校验字段。
MBAP 报文头一共 7 个字节,结构如下:
| 字段 | 长度 | 说明 |
|---|---|---|
| 事务处理标识符 | 2 字节 | 用于请求/响应的配对,我习惯用递增序号 |
| 协议标识符 | 2 字节 | Modbus 协议固定为 0x0000 |
| 长度 | 2 字节 | 后续数据的字节数(从单元标识符开始算) |
| 单元标识符 | 1 字节 | 相当于 RTU 中的从站地址 |
PDU 部分跟 RTU 一模一样,功能码 + 数据。所以你看,TCP/IP 的帧其实就是给 RTU 的 PDU 套了个 MBAP 头,再把校验去掉。
关键点:MBAP 头里的「长度」字段不包括它自己那 7 个字节。很多新手在这里算错,导致报文解析失败。我曾经在一个项目中排查了整整两天,才发现是长度字段多算了 7 个字节。
下面是我画的一个帧结构对比图,帮你直观理解:
4.2 TCP/IP 与 RTU/ASCII 的映射关系
很多工程师问我:TCP/IP 和 RTU 到底能不能混用?我的回答是:应用层完全兼容,传输层完全不同。
具体来说,映射关系是这样的:
- 功能码和数据:完全一致。你在 RTU 里用 03 功能码读保持寄存器,TCP/IP 里也是 03。
- 从站地址:RTU 里是报文第二个字节,TCP/IP 里变成了 MBAP 头的单元标识符。
- 校验:RTU 用 CRC,ASCII 用 LRC,TCP/IP 不需要——TCP 协议本身已经做了校验和重传。
- 帧结束:RTU 靠 3.5 字符空闲时间判断帧结束,TCP/IP 靠 TCP 的流边界。
我的经验:如果你有一个现成的 RTU 设备想改成 TCP/IP,最简单的办法就是写一个网关程序。把 RTU 的串口数据收上来,去掉 CRC,加上 MBAP 头,然后通过 TCP 发出去。反过来也一样。我在一个老旧工厂改造项目中就这么干过,省了不少设备更换费用。
这里有个常见的坑:单元标识符。有些设备厂商把它当从站地址用,有些则固定为 0xFF。我建议你在调试时先用 Wireshark 抓包看看,确认对方是怎么处理的。我曾经遇到一个 PLC,单元标识符必须跟 MBAP 头里的长度字段有特定关系,折腾了我一整天。
4.3 TCP/IP 连接管理与端口号
Modbus TCP/IP 默认使用 端口 502。这个端口号是 IANA 分配的,几乎所有 Modbus TCP 设备都默认监听这个端口。嗯,这里要注意:502 端口在 Windows 系统上属于特权端口,普通应用程序不能直接绑定。我有个同事就因为这个折腾了半天,最后用管理员权限运行才搞定。
连接管理方面,Modbus TCP/IP 采用典型的 客户端-服务器模型:
- 客户端(主站):主动发起 TCP 连接,发送请求报文。
- 服务器(从站):监听 502 端口,接收请求并回复响应。
关于连接的生命周期,我个人建议遵循以下原则:
- 建立连接:客户端主动发起三次握手。不要一上来就发 Modbus 报文,先确认 TCP 连接建立成功。
- 保持连接:多数设备支持长连接。我习惯用心跳包(空读请求)来维持连接,每 30 秒发一次。
- 断开连接:客户端或服务器都可以主动关闭。注意:有些设备在连接断开后需要等待 2-3 秒才能重新连接。
避坑指南:我曾经在一个项目中,客户端每发一次请求就新建一个 TCP 连接,结果设备在第 100 次左右就崩溃了。原因是设备端的 TCP 资源被耗尽。记住:尽量复用连接,不要频繁建立和断开。
还有一个细节:并发连接数。大多数 Modbus TCP 服务器支持 4-8 个并发连接。如果你的系统有多个客户端同时访问同一台设备,要注意不要超过这个限制。我一般会在客户端做连接池管理,控制并发数。
最后,送你一个调试小技巧:用 Wireshark 抓包时,设置过滤条件 tcp.port == 502,然后观察 TCP 的 SEQ 和 ACK 号。如果发现大量重传报文,说明网络质量有问题,或者设备处理不过来。这时候别急着怀疑 Modbus 协议,先排查网络层。
总结一下:Modbus TCP/IP 的核心就是给 RTU 的 PDU 套了个 MBAP 头,用 TCP 的可靠性替代了 CRC 校验。端口 502 是标配,连接管理要记住「长连接、控并发、用心跳」。搞懂了这些,你在工业以太网调试中就能少走很多弯路。
公众号:蓝海资料掘金营,微信 deep3321