Modbus RTU 与 Modbus TCP 深入指南-串口服务器:RTU转TCP

十二、串口服务器:RTU转TCP

12.1 典型应用场景

问题:工厂有200个Modbus RTU设备(8条RS485总线,每条25个设备),新MES系统只支持Modbus TCP。

解决方案:使用串口服务器(Serial Device Server)或多端口网关。

12.2 架构图

复制代码
MES/SCADA (TCP Client)
        │
        ├── 网关1 (IP: 192.168.1.10) ── RS485总线1 ── RTU设备(地址1-25)
        │
        ├── 网关2 (IP: 192.168.1.11) ── RS485总线2 ── RTU设备(地址1-25)
        │
        ├── 网关3 (IP: 192.168.1.12) ── RS485总线3 ── RTU设备(地址1-25)
        │
        └── 网关... 

12.3 常见方案对比

方案 优点 缺点 适用场景
单端口串口服务器 简单、便宜 每个总线一个IP 少量RTU设备(<32)
多端口网关 节省IP、管理方便 贵、配置复杂 大量RTU设备
软件网关(如MBpoll) 灵活、可定制 需PC、稳定性一般 测试开发
嵌入式网关(Arduino/Pi) 低成本、可控 需开发、维护 定制化需求

12.4 串口服务器配置要点

12.4.1 常见参数
复制代码
工作模式: TCP Server
监听端口: 502
串口参数: 9600/8/N/1
打包时间: 10ms (或4ms)
打包字节: 200
连接模式: 允许最多5个TCP客户端
12.4.2 地址映射策略
策略 说明 示例
每个网关一个IP 通过IP区分总线 网关1:192.168.1.10, 网关2:192.168.1.11
每个网关一个端口 通过端口区分总线 网关:502→总线1, 503→总线2
单元ID路由 通过MBAP单元ID区分 单元ID1-25→总线1, 26-50→总线2

12.5 实际部署坑点与解决

12.5.1 超时设置问题

问题:网关默认超时200ms,但RTU长距离19200bps下读32个寄存器需280ms。

解决:网关超时调整至500ms。

bash 复制代码
# Moxa NPort配置示例
set timeout=500  # 毫秒
12.5.2 广播风暴

问题:MES误发功能码43(设备识别)扫描所有设备,导致总线阻塞。

解决:网关过滤未实现的功能码。

python 复制代码
# 网关转发逻辑
def forward_filter(pdu):
    func = pdu[0]
    # 只转发常用功能码
    if func in [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0F, 0x10]:
        return True
    else:
        # 返回异常响应(非法功能)
        send_exception(pdu, 0x01)
        return False
12.5.3 连接数限制

问题:多个MES客户端同时访问,但网关只允许1个TCP连接。

解决:使用支持多连接的网关(如Moxa NPort 5150支持5个连接),或前端加负载均衡。

12.6 Python软件网关示例

python

python 复制代码
import socket
import serial
import threading

class ModbusRTUtoTCPGateway:
    def __init__(self, serial_port, baudrate=9600, tcp_port=502):
        self.serial = serial.Serial(serial_port, baudrate, timeout=0.1)
        self.tcp_port = tcp_port
        
    def start(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server.bind(('0.0.0.0', self.tcp_port))
        server.listen(5)
        print(f"Gateway listening on port {self.tcp_port}")
        
        while True:
            client, addr = server.accept()
            print(f"TCP client connected: {addr}")
            threading.Thread(target=self.handle_client, args=(client,)).start()
    
    def handle_client(self, client):
        try:
            while True:
                # 接收TCP请求
                mbap = client.recv(7)
                if len(mbap) < 7:
                    break
                
                trans_id, proto_id, length, unit_id = struct.unpack('>HHHB', mbap)
                pdu = client.recv(length - 1)
                
                # 转换为RTU帧
                rtu_frame = bytes([unit_id]) + pdu
                crc = modbus_crc(rtu_frame)
                rtu_frame += crc.to_bytes(2, 'little')
                
                # 发送到串口
                self.serial.write(rtu_frame)
                
                # 等待RTU响应(3.5字符间隔)
                time.sleep(0.004)  # 4ms
                response = self.serial.read(256)
                
                # 解析RTU响应
                if len(response) < 5:
                    continue
                
                # 验证CRC,提取数据
                recv_crc = (response[-2] << 8) | response[-1]
                calc_crc = modbus_crc(response[:-2])
                if recv_crc != calc_crc:
                    continue
                
                # 转换为TCP响应
                resp_unit_id = response[0]
                resp_pdu = response[1:-2]
                resp_mbap = struct.pack('>HHHB', trans_id, 0, len(resp_pdu)+1, resp_unit_id)
                
                # 发回TCP客户端
                client.send(resp_mbap + resp_pdu)
        except Exception as e:
            print(f"Error: {e}")
        finally:
            client.close()

# 启动网关
gateway = ModbusRTUtoTCPGateway('/dev/ttyUSB0', 9600, 502)
gateway.start()
相关推荐
银河外卖员1 小时前
VMware Workstation Pro 安装详细图文操作教程
运维·服务器
H Journey1 小时前
网络编程:Linux下高性能TCP网络服务器(代码完整版)多线程版本
linux·服务器·网络
七七powerful1 小时前
AI+运维提效,ssl-cert-monitoring(SSL证书监控系统)2.0开发完毕
运维·网络协议·ssl
CableTech_SQH1 小时前
F5G全光网络二层扁平架构技术拆解:OLT+ODN+ONU全链路原理详解
大数据·网络·5g·信息与通信
CDN3601 小时前
告别TCP队头阻塞!HTTP/3与QUIC协议在2026年的实战落地
网络协议·tcp/ip·http
微风凉凉起1 小时前
复现漏洞 CVE-2026-31431
服务器
yqcoder1 小时前
深入理解 JavaScript:什么是可迭代对象 (Iterable)?
开发语言·javascript·网络
原来是猿1 小时前
JSON 序列化与反序列化 —— 用 Jsoncpp 打造自己的网络协议
网络·网络协议·json
@insist1231 小时前
信息安全工程师-入侵阻断与网络流量清洗技术详解
网络·安全·软考·信息安全工程师·软件水平考试