Modbus TCP 数据结构(发送和返回/读/写)

Modbus TCP通信协议完整字节级详解

📌 本文提供Modbus TCP协议每个字节的详细说明,包括帧头、功能码、数据字段的精确位置和含义,是调试和开发Modbus TCP的必备参考手册。

1. 📊 Modbus TCP帧结构总览

1.1 完整帧格式(字节级分解)

复制代码
字节位置: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 ... N
字段:    [---MBAP头(7字节)---] [---------PDU(变长)---------]
         T  T  P  P  L  L  U  F
         I  I  I  I  H  L  I  C
         D  D  H  L  H  L  D
         H  L                   + 功能码 + 数据

1.2 MBAP头固定格式(7字节)

字节偏移 字段名称 长度 固定值 说明
0 事务标识符高字节 1字节 0x00-0xFF 请求ID高8位
1 事务标识符低字节 1字节 0x00-0xFF 请求ID低8位
2 协议标识符高字节 1字节 0x00 固定为0
3 协议标识符低字节 1字节 0x00 固定为0
4 长度字段高字节 1字节 0x00 后续字节数高8位
5 长度字段低字节 1字节 0xXX 后续字节数低8位
6 单元标识符 1字节 0x01-0xFF 从站地址

重要公式:长度字段 = 单元标识符(1) + 功能码(1) + 数据字节数

或者更准确地:
长度字段 = 从单元标识符开始到报文结束的总字节数


2. 📖 功能码0x03:读保持寄存器

2.1 请求帧(客户端→服务器)

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11
值:  [T  T  P  P  L  L  U  F  S  S  Q  Q]
     I  I  I  I  H  L  I  C  A  A  T  T
     D  D  H  L  H  L  D     H  L  H  L
示例:00 01 00 00 00 06 01 03 00 0A 00 03
字节偏移 字段名称 长度 示例值 详细说明
0-1 事务标识符 2字节 0x0001 每次请求递增
2-3 协议标识符 2字节 0x0000 Modbus TCP固定
4-5 长度 2字节 0x0006 后续6字节
6 单元标识符 1字节 0x01 设备地址1
7 功能码 1字节 0x03 读保持寄存器
8-9 起始地址 2字节 0x000A 从地址10开始
10-11 寄存器数量 2字节 0x0003 读取3个寄存器

帧长度:固定12字节

2.2 响应帧(服务器→客户端)

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11 12 13
值:  [T  T  P  P  L  L  U  F  B  D  D  D  D  D]
     I  I  I  I  H  L  I  C  C
     D  D  H  L  H  L  D        + 寄存器数据
示例:00 01 00 00 00 09 01 03 06 00 12 00 34 00 56
字节偏移 字段名称 长度 示例值 详细说明
0-1 事务标识符 2字节 0x0001 同请求帧
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x0009 后续9字节(1+1+1+6)
6 单元标识符 1字节 0x01
7 功能码 1字节 0x03
8 字节计数 1字节 0x06 寄存器数×2=6
9-10 寄存器1值 2字节 0x0012 高字节在9,低字节在10
11-12 寄存器2值 2字节 0x0034 寄存器11的值
13-14 寄存器3值 2字节 0x0056 寄存器12的值

长度计算:7 + 1 + 1 + 1 + (寄存器数×2) = 9 + 6 = 15字节


3. 🔍 功能码0x04:读输入寄存器

3.1 请求帧

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11
值:  [T  T  P  P  L  L  U  F  S  S  Q  Q]
     I  I  I  I  H  L  I  C  A  A  T  T
     D  D  H  L  H  L  D     H  L  H  L
示例:00 02 00 00 00 06 01 04 00 05 00 02
字节偏移 字段名称 长度 示例值 说明
0-1 事务标识符 2字节 0x0002 ID=2
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x0006
6 单元标识符 1字节 0x01
7 功能码 1字节 0x04 读输入寄存器
8-9 起始地址 2字节 0x0005 地址5
10-11 寄存器数量 2字节 0x0002 读取2个

3.2 响应帧

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11 12
值:  [T  T  P  P  L  L  U  F  B  D  D  D  D]
示例:00 02 00 00 00 07 01 04 04 12 34 56 78
字节偏移 字段名称 长度 示例值 说明
0-1 事务标识符 2字节 0x0002
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x0007 后续7字节
6 单元标识符 1字节 0x01
7 功能码 1字节 0x04
8 字节计数 1字节 0x04 2×2=4字节
9-10 寄存器1值 2字节 0x1234 高字节在9
11-12 寄存器2值 2字节 0x5678 高字节在11

字节12:最后一个数据的低字节


4. ✍️ 功能码0x06:写单个寄存器

4.1 请求帧

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11
值:  [T  T  P  P  L  L  U  F  S  S  D  D]
     I  I  I  I  H  L  I  C  A  A  H  L
     D  D  H  L  H  L  D     H  L
示例:00 03 00 00 00 06 01 06 00 0F 12 34
字节偏移 字段名称 长度 示例值 详细说明
0-1 事务标识符 2字节 0x0003 ID=3
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x0006 后续6字节
6 单元标识符 1字节 0x01
7 功能码 1字节 0x06 写单个寄存器
8-9 寄存器地址 2字节 0x000F 寄存器15
10-11 寄存器值 2字节 0x1234 写入值0x1234

字节10:写入值的高字节

字节11:写入值的低字节

4.2 响应帧

重要:响应帧与请求帧完全相同

复制代码
00 03 00 00 00 06 01 06 00 0F 12 34

字节位置完全对应


5. 📝 功能码0x10:写多个寄存器

5.1 请求帧

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18
值:  [T  T  P  P  L  L  U  F  S  S  Q  Q  B  D  D  D  D  D  D]
     I  I  I  I  H  L  I  C  A  A  T  T  C
     D  D  H  L  H  L  D     H  L  H  L
示例:00 04 00 00 00 0B 01 10 00 20 00 03 06 11 11 22 22 33 33
字节偏移 字段名称 长度 示例值 详细说明
0-1 事务标识符 2字节 0x0004 ID=4
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x000B 后续11字节
6 单元标识符 1字节 0x01
7 功能码 1字节 0x10 写多个寄存器
8-9 起始地址 2字节 0x0020 从地址32开始
10-11 寄存器数量 2字节 0x0003 写入3个寄存器
12 字节计数 1字节 0x06 3×2=6字节
13-14 寄存器1值 2字节 0x1111 字节13=高,14=低
15-16 寄存器2值 2字节 0x2222 字节15=高,16=低
17-18 寄存器3值 2字节 0x3333 字节17=高,18=低

字节12是关键:它告诉服务器后面有多少数据字节

5.2 响应帧

复制代码
字节: 0  1  2  3  4  5  6  7  8  9 10 11
值:  [T  T  P  P  L  L  U  F  S  S  Q  Q]
示例:00 04 00 00 00 06 01 10 00 20 00 03
字节偏移 字段名称 长度 示例值 说明
0-1 事务标识符 2字节 0x0004
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x0006 后续6字节
6 单元标识符 1字节 0x01
7 功能码 1字节 0x10
8-9 起始地址 2字节 0x0020 回显地址
10-11 寄存器数量 2字节 0x0003 回显数量

6. ❌ 错误响应格式(所有功能码通用)

6.1 错误响应帧格式

复制代码
字节: 0  1  2  3  4  5  6  7  8
值:  [T  T  P  P  L  L  U  E  C]
     I  I  I  I  H  L  I  F  O
     D  D  H  L  H  L  D  C  D
示例:00 01 00 00 00 03 01 83 02
字节偏移 字段名称 长度 示例值 详细说明
0-1 事务标识符 2字节 同请求 与请求相同
2-3 协议标识符 2字节 0x0000
4-5 长度 2字节 0x0003 后续3字节
6 单元标识符 1字节 同请求
7 错误功能码 1字节 0x8X 原功能码+0x80
8 异常码 1字节 错误码 具体错误原因

6.2 各功能码错误码对应

原功能码 错误功能码 含义
0x03 0x83 读保持寄存器错误
0x04 0x84 读输入寄存器错误
0x06 0x86 写单个寄存器错误
0x10 0x90 写多个寄存器错误

6.3 异常码详解

异常码 名称 含义
0x01 非法功能码 服务器不支持此功能
0x02 非法数据地址 请求地址不存在
0x03 非法数据值 数据值超出范围
0x04 从站设备故障 服务器执行失败
0x05 确认 服务器已接受请求正在处理
0x06 从站设备忙 服务器正忙
0x07 负确认 服务器无法执行
0x08 存储奇偶性错 内存校验错误

7. 📊 字节偏移速查表

7.1 通用位置(所有帧)

字节 字段 长度 值域 备注
0-1 事务标识符 2 0x0000-0xFFFF 客户端维护
2-3 协议标识符 2 0x0000 固定
4-5 长度字段 2 可变 后续字节数
6 单元标识符 1 0x01-0xFF 从站地址
7 功能码 1 见功能码表

7.2 各功能码数据起始位置

功能码 操作 数据开始字节 示例偏移 说明
0x03 读保持寄存器请求 8 8-9:地址, 10-11:数量
0x03 读保持寄存器响应 9 9-10:第一个值 字节8是计数
0x04 读输入寄存器请求 8 同0x03
0x04 读输入寄存器响应 9 同0x03
0x06 写单个寄存器请求 8 8-9:地址, 10-11:值
0x06 写单个寄存器响应 8 同请求 完全回显
0x10 写多个寄存器请求 8 8-9:地址, 10-11:数量, 12:计数, 13+:数据 字节13是第一个数据高字节
0x10 写多个寄存器响应 8 8-9:地址, 10-11:数量 只回显地址和数量

7.3 关键字节位置记忆

  • 字节6:总是单元标识符

  • 字节7:总是功能码

  • 字节8-9:通常是地址(0x03/0x04/0x06/0x10请求)

  • 字节10-11:通常是数量或数据(0x03/0x04数量,0x06数据)

  • 字节12:0x10请求的字节计数

  • 字节13:0x10请求的第一个数据高字节


8. 🎯 字节级分析示例

示例1:0x10写多个寄存器帧分析

复制代码
收到帧: 00 04 00 00 00 0B 01 10 00 20 00 03 06 11 11 22 22 33 33
逐字节分析:
字节0: 0x00 事务ID高
字节1: 0x04 事务ID低 → ID=0x0004
字节2: 0x00 协议ID高
字节3: 0x00 协议ID低 → 协议=0x0000
字节4: 0x00 长度高
字节5: 0x0B 长度低 → 长度=0x000B=11字节
字节6: 0x01 单元标识符 → 设备地址1
字节7: 0x10 功能码 → 写多个寄存器
字节8: 0x00 起始地址高
字节9: 0x20 起始地址低 → 地址=0x0020=32
字节10: 0x00 寄存器数量高
字节11: 0x03 寄存器数量低 → 数量=0x0003=3个
字节12: 0x06 字节计数 → 3×2=6字节
字节13: 0x11 第一个寄存器值高字节
字节14: 0x11 第一个寄存器值低字节 → 值=0x1111=4369
字节15: 0x22 第二个寄存器值高字节
字节16: 0x22 第二个寄存器值低字节 → 值=0x2222=8738
字节17: 0x33 第三个寄存器值高字节
字节18: 0x33 第三个寄存器值低字节 → 值=0x3333=13107

示例2:0x03读保持寄存器响应分析

复制代码
收到帧: 00 01 00 00 00 09 01 03 06 00 12 00 34 00 56
字节0-1: 0x0001 事务ID
字节2-3: 0x0000 协议ID
字节4-5: 0x0009 长度 → 后续9字节
字节6: 0x01 单元ID
字节7: 0x03 功能码 → 读保持寄存器
字节8: 0x06 字节计数 → 6字节数据
字节9: 0x00 第一个值高 → 寄存器1值高
字节10: 0x12 第一个值低 → 寄存器1值=0x0012=18
字节11: 0x00 第二个值高 → 寄存器2值高
字节12: 0x34 第二个值低 → 寄存器2值=0x0034=52
字节13: 0x00 第三个值高 → 寄存器3值高
字节14: 0x56 第三个值低 → 寄存器3值=0x0056=86

9. ✅ 调试检查清单

9.1 发送前检查

  • \] 事务ID是否正确递增

  • \] 长度字段计算是否正确

  • \] 地址是否在有效范围

  • \] 字节计数(0x10)是否正确

  • \] 事务ID是否匹配请求

  • \] 字节计数是否匹配

  • \] 异常码处理

问题现象 可能原因 检查字节
无响应 网络问题/设备离线 所有
错误响应0x83/0x84 功能码错误 字节7
错误响应0x02 地址错误 字节8-9
错误响应0x03 数据值错误 字节10-11或13+
数据不全 数量太多 字节10-11
字节不匹配 长度错误 字节4-5

📊 总结:核心字节位置

功能 关键字节 作用 示例
所有请求 字节6 设备地址 0x01=地址1
字节7 功能码 0x03=读保持
0x03/0x04请求 字节8-9 起始地址 0x000A=地址10
字节10-11 寄存器数量 0x0003=3个
0x06请求 字节8-9 寄存器地址 0x000F=地址15
字节10-11 写入值 0x1234=写入值
0x10请求 字节8-9 起始地址 0x0020=地址32
字节10-11 寄存器数量 0x0003=3个
字节12 字节计数 0x06=6字节
字节13+ 寄存器值 从13开始
响应帧 字节8 字节计数 0x06=6字节数据
字节9+ 寄存器值 从9开始

掌握这些字节级信息,您可以:

  1. ✅ 精确构造任意Modbus TCP帧

  2. ✅ 快速定位通信问题

  3. ✅ 高效调试协议交互

  4. ✅ 实现可靠的工业通信

本文提供的字节级细节是Modbus TCP开发、调试和分析的核心参考,建议保存以备查阅。

如何计算长度????

相关推荐
鱼很腾apoc1 小时前
【实战篇】 第13期 算法竞赛_数据结构超详解(上)
c语言·开发语言·数据结构·学习·算法·青少年编程
虾说羊1 小时前
WebSocket讲解
网络·websocket·网络协议
小李独爱秋1 小时前
计算机网络经典问题透视——IP电话的两大主要信令标准各有何特点?
网络协议·tcp/ip·计算机网络·ip电话
数通工程师2 小时前
进阶指南:如何利用 SecureCRT 打造“一键式”自动化数据采集方案?
运维·网络·网络协议·tcp/ip·自动化·运维开发
tobias.b2 小时前
408真题解析-2009-42-数据结构-单链表与双指针技巧
数据结构·计算机考研·408真题解析
这儿有一堆花2 小时前
互联网通信的双引擎:全面解析 TCP/IP 与 UDP
网络协议·tcp/ip·udp
666HZ6662 小时前
数据结构3.0 栈、队列和数组
开发语言·数据结构·算法
yzs872 小时前
GreenPlum/Cloudberry UDP数据连接及接收缓存
网络·网络协议·缓存·udp
tobias.b2 小时前
408真题解析-2009-41-数据结构-最短路径
数据结构·算法·计算机考研·408考研·408真题解析