4. Modbus TCP详解
Modbus TCP 是 Modbus 协议在以太网上的承载方式。它把传统 Modbus RTU 的串行帧结构改造成“TCP/IP 传输 + MBAP 报文头 + PDU”的组合,使网关、PLC、SCADA 和云平台之间可以通过标准以太网交换数据。理解 Modbus TCP,关键不是记住“它跑在 502 端口”,而是看清 TCP/IP 提供了什么、MBAP 又补充了什么,以及事务标识、协议标识和长度字段如何保证请求与响应正确配对。
一、TCP/IP基础:Modbus TCP 的传输底座
Modbus TCP 使用 TCP 作为传输层协议,默认端口号为 502。TCP 提供面向连接、可靠、有序的字节流服务,因此 Modbus TCP 不需要像 Modbus RTU 那样依赖 CRC 校验来发现传输错误,也不需要 3.5 字符间隔来划分帧边界。帧边界由 MBAP 中的长度字段和 TCP 流本身来界定。
一次典型的 Modbus TCP 通信过程如下:客户端(如 SCADA、网关)向服务器(如 PLC、Modbus TCP 从站)发起 TCP 连接;连接建立后,客户端发送请求报文;服务器解析 MBAP 和 PDU,执行操作后返回响应;双方可在一个 TCP 连接上连续进行多次事务。由于 TCP 是字节流,接收方必须根据 MBAP 长度字段准确切分每一帧,不能假设“一次 recv 就是一条完整报文”。
二、MBAP报文头:Modbus TCP 的“信封”
MBAP(Modbus Application Protocol)报文头位于 PDU 之前,共 7 个字节,是 Modbus TCP 区别于 Modbus RTU 的核心标志。它包含四个字段:事务标识符、协议标识符、长度字段和单元标识符。MBAP 的作用是让接收方知道“这是哪一次事务、是不是 Modbus、后面还有多少字节、目标是从站还是网关后面的某个串口设备”。
| 字段 | 长度 | 典型值/说明 | 作用 |
|---|---|---|---|
| 事务标识符 | 2 字节 | 由客户端递增或随机生成 | 匹配请求与响应,支持并发事务 |
| 协议标识符 | 2 字节 | 0x0000 表示 Modbus | 标识上层协议类型 |
| 长度字段 | 2 字节 | 后续字节数,含单元标识符 | 界定报文边界,防止粘包/拆包 |
| 单元标识符 | 1 字节 | 0x01~0xFF,网关常用 0x01 | 标识目标从站或网关后端设备 |
三、事务标识、协议标识与长度字段的协作
事务标识符(Transaction ID)由客户端生成,服务器在响应中原样返回。客户端收到响应后,用事务标识符判断“这是不是我刚才发出的那条请求的回复”。在并发请求较多的 SCADA 系统中,事务标识符是避免响应错配的关键。若客户端同时发出多个请求,事务标识符必须不同;若相同,客户端将无法区分响应归属。
协议标识符(Protocol ID)固定为 0x0000,表示这是 Modbus 协议。如果收到非 0 值,接收方应丢弃或报错。长度字段(Length)表示从单元标识符开始到 PDU 结束的字节数,即“单元标识符 1 字节 + PDU 长度”。例如,读保持寄存器请求的 PDU 为 5 字节(功能码 1 字节 + 起始地址 2 字节 + 寄存器数量 2 字节),则长度字段为 1 + 5 = 6。接收方先读 7 字节 MBAP,再根据长度字段读取剩余字节,从而准确切分报文。
四、案例:一次读保持寄存器请求的报文拆解
假设客户端要读取从站 1 的保持寄存器,起始地址 0x0000,数量 0x000A。功能码为 0x03。其 Modbus TCP 请求报文(十六进制)如下:
事务标识符:0x0001
协议标识符:0x0000
长度字段:0x0006
单元标识符:0x01
功能码:0x03
起始地址:0x0000
寄存器数量:0x000A
完整报文:
00 01 00 00 00 06 01 03 00 00 00 0A
服务器返回响应时,事务标识符仍为 0x0001,协议标识符为 0x0000,长度字段为 0x0005 + 2×10 = 0x0017(单元标识符 1 字节 + 功能码 1 字节 + 字节数 1 字节 + 20 字节数据 = 23 字节,即 0x17)。客户端收到后,先核对事务标识符,再根据长度字段读取完整数据。若事务标识符不匹配,说明该响应属于其他请求,应丢弃或重新匹配。
五、常见误区与排障复盘
- 误区一:把单元标识符当成从站地址。在 Modbus TCP 直连设备中,单元标识符常被忽略或固定为 0x01;但在网关场景中,它用于指定网关后端的 Modbus RTU 从站地址,必须与后端设备地址一致。
- 误区二:忽略长度字段导致粘包。TCP 是字节流,若接收方不按长度字段切分,可能把两条响应拼在一起,造成解析错位。正确做法是先读 7 字节 MBAP,再根据长度字段读取剩余字节。
- 误区三:事务标识符重复。并发请求时若事务标识符重复,响应无法正确配对。建议客户端使用递增计数器,并处理回绕。
- 误区四:协议标识符非 0 仍继续解析。协议标识符必须为 0x0000,否则应丢弃报文并记录异常,避免误解析非 Modbus 流量。
总结来说,Modbus TCP 的可靠性来自 TCP,而可解析性来自 MBAP。事务标识符负责“配对”,协议标识符负责“认协议”,长度字段负责“切边界”,单元标识符负责“找设备”。在网关集成中,只有把这四个字段与 TCP/IP 连接管理结合起来,才能稳定地完成 Modbus RTU 与 Modbus TCP 之间的协议转换和数据转发。