

近期在调试一套工业环境监控系统时,遇到了关于 Modbus 连接保持的问题。现场部署了一批网口温湿度变送器,PoE取电、Modbus TCP上云,同时利旧接入存量RS485探头,并开启了UDP Trap事件上报。把UDP和Modbus TCP放在同一张网里跑通之后,选型问题浮出水面:什么时候用TCP,什么时候用UDP,能不能只用一种?这篇把两种协议的本质差异拆开,落到温湿度传感网络的工程选型上。
应用层:Modbus TCP(请求/响应、功能码、寄存器模型)
传输层:TCP(面向连接、可靠、有序、流控)
网络层:IP
链路层:以太网应用层:私有UDP Trap / SNMP Trap(事件通知、无状态)
传输层:UDP(无连接、不可靠、无流控)
网络层:IP
链路层:以太网关键差异一句话:Modbus TCP是"打电话"——拨通、对话、挂断,确保每一句都听到;UDP是"发传单"——印好、撒出去、不管对方收没收到。
维度 | Modbus TCP | UDP |
|---|---|---|
连接方式 | 面向连接(三次握手、四次挥手) | 无连接(直接发包) |
可靠性 | 确认重传、去重、有序交付 | 不保证到达、不保证顺序 |
流控/拥塞控制 | 滑动窗口、慢启动、拥塞避免 | 无,应用层自己管 |
报文开销 | TCP头20B + MBAP头7B = 27B | UDP头8B + 应用头 = 8~16B |
交互模型 | 请求/响应(一问一答) | 请求/响应 或 通知/不等待 |
并发模型 | 每连接一个PCB,低端MCU受限 | 无状态,单端口可收任意源 |
传输延迟 | 建连+确认,延迟较高 | 直接发送,延迟极低 |
断线检测 | Keep-alive、RST | 无原生机制 |
典型用途 | 全量采集、下发控制、配置读写 | 事件告警、Trap、快报 |
Modbus TCP 采集:
网关 → 传感器:Read Input Registers (FC04), 起始0x0000, 数量4
传感器 → 网关:响应, 数据8字节(温度、湿度、露点、状态)UDP Trap 推送:
传感器 → 网关:温度=23.5℃, 湿度=55.2%RH, 越限标志=0场景 | Modbus TCP | UDP |
|---|---|---|
网络闪断 | 连接断开,重连后继续 | 丢包,应用层需检测 |
交换机拥塞 | TCP自动降速,排队 | UDP可能丢包或延迟 |
MCU资源耗尽 | 拒绝新连接、RST | 直接丢弃,无通知 |
网关重启 | TCP连接断开,重连 | 传感器不知道,继续发 |
这是推荐方案。
Modbus TCP → 全量基线采集(周期30s)
UDP Trap → 事件快报(变化即报)现象:传感器UDP Trap推送温湿度,网关偶尔收不到,画面显示最后已知值,没人发现异常。
根因:UDP不保证到达,网络闪断、交换机拥塞、pbuf池耗尽都会丢包。没有重传机制,传感器不知道网关没收到。
解法:
现象:86个传感器,每个30s轮询一次,网关并发连接数不够,部分传感器RST。
根因:低端MCU Modbus TCP栈常限1–2个并发连接。多主站(SCADA + 云端 + 调试)同时访问,连接槽占满。
解法:
现象:恒湿机启动,温湿度突变,所有传感器同时发UDP Trap,网关pbuf池耗尽,TCP连接也受影响。
根因:UDP无流控,传感器不知道网关处理能力。
解法:
现象:传感器和网关TCP连接建立后,空闲一段时间自动断开,重连时RST。
根因:交换机/防火墙有TCP空闲超时(默认15–30min),静默丢弃连接跟踪表项。传感器侧未启用TCP Keep-alive。
解法:
传感器
├── Modbus TCP (502) → 全量采集,周期30s
│ └── 网关 → SCADA / 云端
└── UDP Trap (9000) → 事件快报,变化即报
└── 网关 → 实时告警 / 联动触发通道 | 方向 | 内容 | 周期 | 可靠性 |
|---|---|---|---|---|
TCP | 网关→传感器→网关 | 全量寄存器(温湿度、露点、状态、配置) | 30s | 重传、有序 |
UDP | 传感器→网关 | 越限事件、状态变化 | 变化即报 | 不保证,网关超时兜底 |
# 伪代码:双通道融合
# TCP采集线程
def tcp_poll():
while True:
regs = modbus_read(ip, 502, fc=4, start=0, count=8)
ts = time.now()
influx.write(tags, regs, time=ts)
time.sleep(30)
# UDP接收线程
def udp_receive():
sock = socket.socket(AF_INET, SOCK_DGRAM)
sock.bind(('0.0.0.0', 9000))
while True:
data, addr = sock.recvfrom(1024)
if verify_hmac(data):
event = parse_trap(data)
trigger_alarm(event)
# 同时触发一次TCP全量采集,确认当前状态
queue.put(('tcp_poll_now', addr))场景 | 推荐方案 | 理由 |
|---|---|---|
新建库区,点位<50,网络好 | Modbus TCP 单通道 | 简单可靠,运维成本低 |
新建库区,点位>100 | TCP全量 + UDP事件 | 连接池可控,异常实时通知 |
利旧改造,存量RS485 | 网关代理,南向RTU,北向TCP | 统一上云,不改末端 |
无人值守,断网自治 | TCP + 本地缓存 | 断网续传,TCP重连后补传 |
消防联动,低延迟 | UDP Trap + 硬接线兜底 | 毫秒级通知,安全不依赖网络 |
多主站访问 | 网关代理,SCADA经OPC UA | 连接收敛,避免RST |
Modbus TCP和UDP不是"选一个"的关系,而是"各管一段"的分工:TCP管确定性(我知道现在是什么状态),UDP管实时性(异常时第一时间通知)。 工业温湿度传感网络,推荐TCP全量采集 + UDP事件快报的双通道架构,网关侧融合,边缘侧归一化。选型时先算连接数、再算报文量、最后看延迟要求,别让协议选型成为系统瓶颈。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。