工业通信协议
工业通信协议(Industrial Communication Protocol)是工业 AI 系统的数据采集层——它定义了上位机(host PC)与 PLC、传感器、变频器等现场设备之间”如何说话”的规则。如果把工业 AI 比作一个人,那么视觉算法是眼睛、控制逻辑是大脑,而通信协议就是连接它们的神经系统。本页从 TCP/IP 底层原理出发,逐步覆盖 Socket 编程、Modbus TCP、OPC UA、MQTT 以及 PLC 专有协议,帮你打通”从设备到 AI 模型”的数据链路。
本页是 工业 AI 系统 的前置知识,同时与 数据库与中间件 中的时序数据库、消息队列章节紧密衔接——采集到的数据最终需要落盘存储和流式处理。
理解工业通信,只需抓住三个层次:
| 层次 | 核心问题 | 代表协议 |
|---|---|---|
| 应用层 | 读什么寄存器?数据格式是什么? | Modbus、OPC UA、MQTT |
| 传输层 | 数据怎么可靠送达? | TCP/IP |
| 物理层 | 信号怎么在线缆上跑? | RS-485、工业以太网 |
一句话直觉:应用层协议解决”读什么”,TCP 解决”怎么送达”,物理层解决”怎么跑线”。工业通信的复杂性主要在应用层。
TCP/IP 基础
Section titled “TCP/IP 基础”TCP(Transmission Control Protocol,传输控制协议)是几乎所有工业以太网协议的底层载体。理解 TCP 的行为,是调试工业通信问题的基本功。
三次握手与四次挥手
Section titled “三次握手与四次挥手”TCP 是面向连接的协议——数据传输前必须先建立连接,传输结束后要优雅断开。
三次握手(Three-Way Handshake) 建立连接的过程:
客户端 服务端 | ──── SYN (seq=x) ────────→ | | ←── SYN-ACK (seq=y, ack=x+1) | | ──── ACK (ack=y+1) ──────→ | | 连接建立 ✓ |- SYN(Synchronize,同步):客户端发起连接请求,携带初始序列号
x。 - SYN-ACK(Synchronize-Acknowledge):服务端确认并附上自己的初始序列号
y。 - ACK(Acknowledge,确认):客户端最终确认,连接进入
ESTABLISHED状态。
四次挥手(Four-Way Handshake) 断开连接:
客户端 服务端 | ──── FIN ────────────────→ | | ←── ACK ─────────────────── | | ←── FIN ─────────────────── | | ──── ACK ────────────────→ | | 连接关闭 ✓ |TCP 是全双工(full-duplex,即双方可同时收发)的,所以每个方向的关闭需要单独完成 FIN→ACK,共四个报文。
粘包与拆包问题
Section titled “粘包与拆包问题”TCP 是流式协议(stream protocol)——它没有”消息边界”的概念。发送方调用两次 send() 各发 100 字节,接收方可能一次性 recv() 收到 200 字节;反之,一次 send() 发 2000 字节也可能被拆成两个包到达。这就是经典的粘包/拆包问题。
工业通信中解决此问题的常见方案:
| 方案 | 原理 | 代表协议 |
|---|---|---|
| 固定长度 | 每条消息恰好 N 字节 | 部分串行协议 |
| 长度前缀(length prefix) | 消息头前几个字节标注后续负载长度 | Modbus TCP(MBAP header 含 length 字段) |
| 分隔符(delimiter) | 用特殊字节序列标记消息结尾 | HTTP(\r\n\r\n)、MQTT(剩余长度编码) |
关键理解:“粘包”不是 TCP 的 bug,而是流式协议的固有特性。应用层协议必须自行定义消息边界。
import struct
def send_message(sock, payload: bytes): """用 4 字节大端长度前缀封装消息,解决 TCP 粘包问题。""" length_prefix = struct.pack('>I', len(payload)) # 4-byte big-endian sock.sendall(length_prefix + payload)
def recv_message(sock) -> bytes: """先读 4 字节长度,再按长度读取完整消息。""" header = _recv_exactly(sock, 4) # 必须收够 4 字节 (length,) = struct.unpack('>I', header) return _recv_exactly(sock, length)
def _recv_exactly(sock, n: int) -> bytes: """循环 recv 直到收满 n 字节——recv 不保证一次返回所需长度。""" buf = bytearray() while len(buf) < n: chunk = sock.recv(n - len(buf)) if not chunk: raise ConnectionError('连接已关闭') buf.extend(chunk) return bytes(buf)长连接 vs 短连接
Section titled “长连接 vs 短连接”- 短连接:每次请求建立 TCP 连接→发数据→关闭连接。优点是简单,缺点是三次握手开销大(典型局域网 RTT 约 0.5 ms,握手就占 1.5 ms)。早期 HTTP/1.0 就是短连接。
- 长连接(keep-alive):建一次连接,多次复用。工业场景几乎都用长连接——PLC 与上位机之间的连接可能保持数月不断开。
TIME_WAIT 问题
Section titled “TIME_WAIT 问题”主动关闭连接的一方会进入 TIME_WAIT 状态,持续 2 MSL(Maximum Segment Lifetime,默认 60 秒 × 2 = 120 秒)。如果服务端频繁重启用同一端口,会因大量 TIME_WAIT 占用而 bind() 失败。
# 查看系统当前的 TIME_WAIT 数量ss -ant | grep TIME-WAIT | wc -l
# 解决方案:设置端口复用# Python 中在 bind() 之前设置 SO_REUSEADDRsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)Socket 编程
Section titled “Socket 编程”Socket(套接字)是操作系统提供的网络通信接口,是所有上层网络库的基石。
基本服务端与客户端
Section titled “基本服务端与客户端”# server.py —— 一个最简 TCP echo serverimport socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)server.bind(('0.0.0.0', 502)) # Modbus 默认端口 502server.listen(5) # backlog = 5 个等待队列
print('等待连接...')conn, addr = server.accept() # 阻塞,直到有客户端连入print(f'客户端 {addr} 已连接')
while True: data = conn.recv(1024) if not data: break conn.sendall(data) # echo 回去
conn.close()# client.py —— 对应的客户端import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(('192.168.1.100', 502))client.sendall(b'\x00\x01\x00\x00\x00\x06\x01\x03\x00\x00\x00\x0a')response = client.recv(1024)print(f'收到响应: {response.hex()}')client.close()I/O 多路复用:select / poll / epoll
Section titled “I/O 多路复用:select / poll / epoll”当服务端需要同时处理数百上千个连接时,为每个连接分配一个线程是不可行的。I/O 多路复用(I/O multiplexing)允许单线程同时监听多个文件描述符(file descriptor, fd)的状态变化。
| 机制 | 最大连接数 | 事件检测方式 | 性能 |
|---|---|---|---|
select | FD_SETSIZE(默认 1024) | 每次调用遍历所有 fd | O(n),最差 |
poll | 无上限 | 同 select,遍历所有 fd | O(n) |
epoll | 无上限 | 内核回调通知,只返回就绪 fd | O(1),最佳 |
epoll 是 Linux 独有的高效机制,也是 Python asyncio、Nginx、Redis 等高性能框架的底层引擎。
epoll 有两种触发模式:
- Level-Triggered(LT,水平触发):只要 fd 的缓冲区有数据可读,
epoll_wait就会持续通知。使用简单,但若不读完数据会反复唤醒。select/poll都是 LT。 - Edge-Triggered(ET,边缘触发):仅在新数据到达的那一瞬间通知一次,后续不再通知,除非又有新数据写入。性能更高(减少系统调用),但要求程序必须一次读完所有数据(用非阻塞 I/O + 循环读至
EAGAIN)。
import select, socket
# epoll 示例(Linux 专属)epoll = select.epoll()server.setblocking(False)epoll.register(server.fileno(), select.EPOLLIN)
connections = {}while True: events = epoll.poll(timeout=1) # 返回就绪 fd 列表 for fd, event in events: if fd == server.fileno(): conn, addr = server.accept() conn.setblocking(False) epoll.register(conn.fileno(), select.EPOLLIN) connections[conn.fileno()] = conn elif event & select.EPOLLIN: data = connections[fd].recv(1024) if data: # 处理数据... pass else: epoll.unregister(fd) connections[fd].close()Python asyncio 的底层就是 epoll——
asyncio将 epoll 封装为事件循环(event loop),配合async/await语法,让你用同步风格的代码获得 epoll 级别的并发性能。详见 Python 工程进阶。
Modbus TCP
Section titled “Modbus TCP”Modbus 由 Modicon 公司(现施耐德电气)于 1979 年发明,是工业领域使用最广泛的通信协议——没有之一。它极其简单:一个请求,一个响应,没有复杂的握手。Modbus TCP 是其以太网版本(Modbus RTU 是串行版本)。
Modbus 将设备内存抽象为四张表:
| 类型 | 读写 | 数据类型 | 功能码 |
|---|---|---|---|
| 线圈(Coil) | 读/写 | 单 bit | 01 读 / 05 写单个 / 0F 写多个 |
| 离散输入(Discrete Input) | 只读 | 单 bit | 02 读 |
| 保持寄存器(Holding Register) | 读/写 | 16 bit | 03 读 / 06 写单个 / 10 写多个 |
| 输入寄存器(Input Register) | 只读 | 16 bit | 04 读 |
记忆技巧:Coil 和 Discrete Input 是”开关量”(1 bit),Holding Register 和 Input Register 是”数值量”(16 bit)。带”Input”的都是只读。
MBAP Header 格式
Section titled “MBAP Header 格式”Modbus TCP 报文前 7 字节是 MBAP(Modbus Application Protocol)header:
Byte: 0-1 2 3-4 5 6 7...字段: 事务ID | 协议ID | 长度 | 单元ID | 功能码 | 数据...长度: 2 B | 2 B | 2 B | 1 B | 1 B | ...- 事务 ID(Transaction ID):2 字节,用于请求/响应配对,客户端自增即可。
- 协议 ID:固定
0x0000(表示 Modbus)。 - 长度:后续字节数(含 Unit ID)。
- 单元 ID(Unit ID):从站地址,串行网络中标识具体设备。
Python pymodbus 读写示例
Section titled “Python pymodbus 读写示例”from pymodbus.client import ModbusTcpClient
# 连接 Modbus TCP 设备(如变频器、PLC 网关)client = ModbusTcpClient('192.168.1.50', port=502, timeout=3)client.connect()
# —— 读取保持寄存器(功能码 03)——# 从地址 0 开始读 10 个寄存器,从站地址 = 1result = client.read_holding_registers(address=0, count=10, slave_id=1)if not result.isError(): print(f'寄存器值: {result.registers}') # 例如 [2300, 0, 500, ...] —— 可能是温度×10、状态码、频率等
# —— 写单个保持寄存器(功能码 06)——client.write_register(address=0, value=2500, slave_id=1)
# —— 读线圈(功能码 01)——coils = client.read_coils(address=0, count=8, slave_id=1)print(f'线圈状态: {coils.bits}') # [True, False, False, ...]
# —— 写线圈(功能码 05)——client.write_coil(address=0, value=True, slave_id=1)
client.close()工程提示:工业现场寄存器的物理含义由设备厂商的”寄存器映射表”(register map / communication manual)定义。Modbus 协议本身不知道地址 0 是”温度”还是”压力”,这需要你查手册。常见陷阱:大端/小端字节序、32 位浮点数需读两个寄存器再拼接、不同厂商的寄存器偏移量差异(PLC 地址 vs 协议地址可能差 1)。
OPC UA
Section titled “OPC UA”OPC UA(OLE for Process Control Unified Architecture,工业统一架构)是 OPC 基金会推出的平台无关的工业通信标准。如果说 Modbus 是”功能机时代的短信”,那 OPC UA 就是”智能手机时代的微信”——功能强大,但复杂度也高得多。
| 概念 | 说明 |
|---|---|
| 节点(Node) | OPC UA 中一切皆节点——传感器、变量、方法、视图,每个节点有唯一 NodeID |
| NodeID | 节点标识符,格式为 ns=<namespace>;i=<numeric> 或 ns=<namespace>;s=<string> |
| 命名空间(Namespace) | 命名空间编号,用于区分不同供应商的节点集合 |
| 地址空间(Address Space) | 所有节点组成的树状结构,类似文件系统 |
| 订阅(Subscription) | 客户端订阅节点变化,服务端主动推送,替代轮询 |
| 安全模式 | None / Sign / SignAndEncrypt,基于 X.509 证书 |
订阅模型 vs 轮询
Section titled “订阅模型 vs 轮询”Modbus 的工作方式是”轮询”(polling)——客户端每隔 100 ms 问一次”温度是多少?“。如果数据没变化,这就是浪费带宽。OPC UA 引入了订阅机制:客户端只需说”温度变化超过 0.5°C 就通知我”,之后服务端会在条件满足时主动推送(publish/notify),大幅降低网络负载。
Python opcua 示例
Section titled “Python opcua 示例”from opcua import Client
client = Client('opc.tcp://192.168.1.60:4840/freeopcua/server/')# client.set_security(...) # 可配置证书加解密
try: client.connect()
# 通过 NodeID 获取节点 temp_node = client.get_node('ns=2;s=Temperature') temperature = temp_node.get_value() print(f'当前温度: {temperature} °C')
# 创建订阅,数据变化时回调 from opcua import Subscription sub = client.create_subscription(period=500, handler=MySubHandler()) handle = sub.subscribe_data_change(temp_node)finally: client.disconnect()
class MySubHandler: """订阅回调处理器。""" def datachange_notification(self, node, val, data): print(f'温度更新: {val} °C (来自 {node.node_id})')OPC UA vs Modbus 对比
Section titled “OPC UA vs Modbus 对比”| 维度 | Modbus TCP | OPC UA |
|---|---|---|
| 复杂度 | 极简,几十行代码上手 | 复杂,概念多 |
| 数据模型 | 扁平寄存器表 | 树状地址空间 + 类型系统 |
| 数据变化通知 | ❌ 只能轮询 | ✅ 订阅推送 |
| 安全性 | 无加密(明文) | 证书签名 + 加密 |
| 语义信息 | 无(靠手册猜含义) | 内含变量名、单位、范围 |
| 适用场景 | 简单设备、成本敏感 | 复杂系统、需要信息模型 |
选型直觉:设备少、协议简单→Modbus;设备多、厂商杂、需要统一数据模型→OPC UA。很多工业网关支持同时做 Modbus master 和 OPC UA server,充当协议转换器。
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是 IBM 于 1999 年发明的轻量级发布/订阅协议,专为带宽受限、网络不稳定的物联网场景设计。它已成为工业 IoT 数据上云的事实标准。
发布/订阅模型
Section titled “发布/订阅模型”与 Modbus 的”点对点请求-响应”不同,MQTT 采用发布/订阅(publish/subscribe)模式,引入一个中间角色——Broker(代理服务器):
- 发布者(Publisher)只管把消息发到某个 topic,不关心谁接收。
- 订阅者(Subscriber)向 Broker 注册感兴趣的 topic,有消息时 Broker 自动推送。
- 解耦:发布者和订阅者之间不需要知道彼此的存在,系统扩展性极强。
Topic 层级设计
Section titled “Topic 层级设计”Topic 用 / 分隔层级,类似文件路径:
factory/floor1/lineA/temperaturefactory/floor1/lineA/pressurefactory/floor1/lineB/temperature订阅时支持通配符:
| 通配符 | 含义 | 示例 |
|---|---|---|
+ | 匹配单层 | factory/+/temperature 匹配所有楼层的温度 |
# | 匹配多层(末尾) | factory/# 匹配 factory 下所有子层级 |
QoS 服务质量
Section titled “QoS 服务质量”MQTT 定义了三个 QoS(Quality of Service)等级:
| 等级 | 名称 | 交付保证 | 握手次数 | 适用场景 |
|---|---|---|---|---|
| QoS 0 | At most once(最多一次) | 不保证送达,不重传 | 1 次(fire and forget) | 高频遥测数据,丢一两条无所谓 |
| QoS 1 | At least once(至少一次) | 保证送达,可能重复 | 2 次(PUBLISH + PUBACK) | 常用默认级别 |
| QoS 2 | Exactly once(恰好一次) | 保证送达且不重复 | 4 次(PUBLISH→PUBREC→PUBREL→PUBCOMP) | 计费、指令等关键消息 |
工程权衡:QoS 2 虽然最可靠,但 4 次握手的开销在低带宽网络下显著。工业遥测数据通常用 QoS 0 或 1;控制指令(如”紧急停机”)才用 QoS 2。
Retain 消息与 Last Will 遗嘱
Section titled “Retain 消息与 Last Will 遗嘱”-
Retain(保留消息):发布时设置
retain=True,Broker 会保存最后一条消息。新的订阅者上线后立即收到这条保留消息,而不需要等下一次数据更新。非常适合”当前状态”类数据(如开关状态、当前温度)。 -
Last Will and Testament(遗嘱机制):客户端连接时可以注册一条”遗嘱消息”。如果客户端异常断开(非正常 disconnect,如断电、网络中断),Broker 会自动发布这条遗嘱消息。订阅者据此得知设备离线。
Mosquitto Broker 配置
Section titled “Mosquitto Broker 配置”Mosquitto 是最流行的开源 MQTT broker:
# 允许匿名访问(生产环境应关闭,配合 password_file)allow_anonymous true
# MQTT 标准端口listener 1883
# WebSocket 端口(供浏览器前端直接连接)listener 9001protocol websockets
# 持久化——将消息和订阅关系保存到磁盘,重启不丢失persistence truepersistence_location /var/lib/mosquitto/
# 最大保持消息数(-1 不限制)max_queued_messages 2000
# 日志log_dest file /var/log/mosquitto/mosquitto.logPython paho-mqtt 示例
Section titled “Python paho-mqtt 示例”import paho.mqtt.client as mqttimport json, time
BROKER = '192.168.1.100'PORT = 1883
# —— 连接回调 ——def on_connect(client, userdata, flags, rc, properties=None): if rc == 0: print('已连接 Broker') client.subscribe('factory/+/temperature', qos=1) # 通配符订阅 else: print(f'连接失败,返回码 {rc}')
# —— 消息到达回调 ——def on_message(client, userdata, msg): payload = json.loads(msg.payload) print(f'[{msg.topic}] 温度={payload["value"]}°C 时间={payload["ts"]}')
client = mqtt.Client( callback_api_version=mqtt.CallbackAPIVersion.VERSION2, client_id='ai-collector-01',)client.on_connect = on_connectclient.on_message = on_message
# 设置遗嘱:设备掉线时通知其他系统client.will_set( topic='device/ai-collector-01/status', payload=json.dumps({'online': False}), qos=1, retain=True,)
client.connect(BROKER, PORT, keepalive=60)client.loop_start() # 后台线程处理网络事件
# —— 模拟发布数据 ——while True: temp = read_sensor() # 假设的传感器读取函数 client.publish( topic='factory/floor1/lineA/temperature', payload=json.dumps({'value': temp, 'ts': time.time()}), qos=1, retain=False, ) time.sleep(1.0)MQTT 采集的数据通常直接写入时序数据库或消息队列进行流处理,详见 数据库与中间件。
PLC 交互与专有协议
Section titled “PLC 交互与专有协议”Modbus 和 OPC UA 虽好,但很多主流 PLC 厂商使用专有协议来暴露更丰富的功能(如直接访问数据块 DB、定时器、计数器等内部资源)。
西门子 S7 协议
Section titled “西门子 S7 协议”西门子(Siemens)S7 系列 PLC(S7-200/300/400/1200/1500)使用 S7comm/S7comm-Plus 协议,底层走 TCP 端口 102(ISO-on-TCP, RFC 1006)。开源库 snap7 提供了完整的 S7 通信实现。
import snap7from snap7.util import get_real, get_int
# 连接西门子 S7-1200/1500 PLCplc = snap7.client.Client()plc.connect('192.168.0.1', rack=0, slot=1)
# 读取数据块 DB1 的前 4 字节(一个 REAL 浮点数)# 参数:db_number, start, sizedata = plc.db_read(db_number=1, start=0, size=4)temperature = get_real(data, 0) # 解析为 IEEE 754 floatprint(f'DB1.DBD0 (温度): {temperature} °C')
# 读取 DB1 的第 4 字节开始的 INT(2 字节有符号整数)data2 = plc.db_read(db_number=1, start=4, size=2)speed = get_int(data2, 0)print(f'DB1.DBW4 (转速): {speed} rpm')
# 写入数据——将设定值写入 DB1.DBW8from snap7.util import set_intwrite_buf = bytearray(2)set_int(write_buf, 0, 1500)plc.db_write(db_number=1, start=8, data=write_buf)
plc.disconnect()注意事项:西门子 S7-1200/1500 默认关闭了”PUT/GET 通信”功能,需要在 TIA Portal 工程中勾选启用,否则 snap7 连接会报权限错误。同时需要在 PLC 属性中勾选”Permit access with PUT/GET communication”。
三菱 MC 协议
Section titled “三菱 MC 协议”三菱(Mitsubishi)PLC 使用 MC Protocol(MELSEC Communication Protocol),支持二进制和 ASCII 两种格式。报文以特定命令帧开头(如 5000 为二进制模式的 MC 请求),支持按设备名(D寄存器、M继电器等)读写。
# 使用 mcprotocol 库(第三方开源)from mcprotocol import MelsecMcA7EBinary
plc = MelsecMcA7EBinary(host='192.168.1.10', port=5000)plc.open()
# 读取 D100 开始 10 个 16 位寄存器values = plc.read_words('D100', 10)print(f'D100-D109: {values}')
plc.close()协议选型矩阵
Section titled “协议选型矩阵”| 维度 | Modbus TCP | OPC UA | S7/MC 专有协议 |
|---|---|---|---|
| 厂商中立 | ✅ 开放标准 | ✅ 开放标准 | ❌ 厂商绑定 |
| 实施难度 | 低 | 中-高 | 低(有库) |
| 数据丰富度 | 寄存器级别 | 带语义的完整信息模型 | 可直接访问 PLC 内部全部资源 |
| 通信效率 | 高 | 中(开销较大) | 高 |
| 实时性 | 毫秒级 | 依赖配置 | 毫秒级 |
| 安全性 | 无 | 证书+加密 | 部分支持 |
| 推荐场景 | 简单设备采集 | 多厂商统一数据平台 | 同厂商 PLC 深度集成 |
协议性能对比
Section titled “协议性能对比”下图为三种主流工业协议在典型 100 Mbps 工业以太网环境下、单连接、约 100 字节小报文场景的延迟与吞吐对比:

解读:MQTT 延迟最低、吞吐最高,但这是因为其报文极轻量且 broker 转发高效;OPC UA 的安全握手和 XML/二进制编码带来额外开销;Modbus 居中,胜在简单稳定。实际性能受网络质量、报文大小、并发连接数等影响。
- 先用 Wireshark 抓包再写代码:Wireshark 内置 Modbus、OPC UA、MQTT 协议解析器(dissector),可以逐字节查看报文。遇到通信问题时,抓包是第一排查手段。
- 超时设置一定要配:工业网络可能因设备重启、线缆松动而中断。务必为每个 socket 设置
timeout,避免线程永久阻塞。 - 断线自动重连:工业场景的连接终会断开(设备维护、网络抖动),程序必须实现指数退避重连逻辑。
- 字节序陷阱:Modbus 使用大端(big-endian),但很多 PLC 默认小端(little-endian)。32 位数据需跨两个寄存器时,注意字交换(word swap)。
- OPC UA 证书管理:生产环境务必启用
SignAndEncrypt模式,妥善管理客户端/服务端 X.509 证书,切勿用None安全模式。
2025–2026 最新进展
Section titled “2025–2026 最新进展”| 趋势 | 说明 |
|---|---|
| OPC UA over TSN | 时间敏感网络(Time-Sensitive Networking)为以太网增加确定性延迟保障,使 OPC UA 可用于硬实时控制场景(≤1 ms 周期),逐步替代传统现场总线 |
| MQTT 5.0 普及 | MQTT 5.0 引入共享订阅(Shared Subscription,多消费者负载均衡)、消息过期、主题别名等功能,2025 年已成为主流 broker(EMQX 5.x、HiveMQ 4.x)的默认选项 |
| Sparkplug B | Eclipse Sparkplug B 规范为工业 MQTT 定义了统一的数据载荷格式和状态管理机制,解决原生 MQTT 缺少设备生命周期管理的问题 |
| OPC UA FX | OPC UA Field eXchange(FX)定义了控制器之间的对等通信标准(PLC-to-PLC),无需中央 OPC UA server,支持去中心化的控制器协同 |
| pymodbus 3.x 重构 | 2024-2025 年 pymodbus 3.x 系列进行了全面异步化重构(asyncio 原生支持),同步/异步双 API 并行,性能提升显著 |
| OPC UA over MQTT (PubSub) | OPC UA 的 PubSub 模式允许通过 MQTT 或 AMQP 作为传输层,融合了 OPC UA 的语义能力和 MQTT 的轻量传输,成为工业 IoT 云端集成的热点方案 |
| 术语 | 英文 | 释义 |
|---|---|---|
| 套接字 | Socket | 操作系统提供的网络通信端点抽象 |
| 多路复用 | I/O Multiplexing | 单线程同时监听多个 I/O 事件的技术 |
| 水平触发 | Level-Triggered (LT) | 只要条件满足就持续通知的模式 |
| 边缘触发 | Edge-Triggered (ET) | 仅在状态变化瞬间通知一次的模式 |
| 线圈 | Coil | Modbus 中可读写的单 bit 数据,源于继电器线圈 |
| 保持寄存器 | Holding Register | Modbus 中可读写的 16 bit 数据单元 |
| 地址空间 | Address Space | OPC UA 中所有节点构成的树状结构 |
| 订阅 | Subscription | 客户端注册兴趣点,服务端数据变化时主动推送 |
| 发布/订阅 | Publish/Subscribe | 发布者与订阅者通过中间代理间接通信的解耦模式 |
| 代理 | Broker | MQTT 中的消息转发中心 |
| 服务质量 | QoS (Quality of Service) | MQTT 定义的交付保证等级(0/1/2) |
| 遗嘱 | Last Will and Testament | MQTT 客户端异常断线时由 broker 代发的通知消息 |
| 保留消息 | Retained Message | Broker 缓存的最后一条消息,新订阅者上线即收到 |
| 现场总线 | Fieldbus | 工业现场设备级的数字通信网络 |
| 时间敏感网络 | TSN (Time-Sensitive Networking) | IEEE 802.1 系列标准,为以太网提供确定性实时通信能力 |
- 本站内:
- 工业 AI 系统架构 —— 了解通信协议在整个工业 AI 系统中的位置
- 工业视觉 —— 视觉检测场景下的数据采集与触发
- 3D 视觉与机器人 —— 机器人控制中的实时通信需求
- 数据库与中间件 —— 采集数据如何落盘与流处理
- Python 工程进阶 —— asyncio 事件循环与 epoll 的深入原理
- 外部资源:
- Modbus Specifications —— 官方协议规范(免费)
- OPC UA Online Reference —— OPC UA 规范全文
- MQTT 5.0 Spec —— OASIS 标准
- pymodbus 文档 —— Python Modbus 库
- snap7 文档 —— Python S7 通信库
- Eclipse Mosquitto —— 开源 MQTT broker
- Wireshark User’s Guide —— 抓包工具(含工业协议解析)