如何将智能电表串口数据可靠复制到多个TCP连接?
解决DSMR 5电表数据多TCP转发的报文对齐问题
方案1:使用ser2net内置多连接转发(推荐)
ser2net原生支持单个串口对应多个TCP监听端口,无需额外工具即可实现无错位转发。直接修改ser2net.yaml配置,为同一个串口设备创建两个独立连接:
connection: &meter_main accepter: tcp,12345 enable: on connector: serialdev, /dev/ttyUSB0, 115200n81,local connection: &meter_secondary accepter: tcp,12346 enable: on connector: serialdev, /dev/ttyUSB0, 115200n81,local
每个TCP连接会独立读取串口原始数据流,ser2net会保证报文边界与TCP数据包对齐,完全匹配原单端口转发的可靠性。
方案2:用socat按报文边界拆分转发
利用DSMR报文以CR+LF结尾的特性,通过socat按完整行(即完整报文)拆分后转发到多端口:
- 创建命名管道:
mkfifo /tmp/dsmr_pipe
- 监听串口并按行写入管道:
socat /dev/ttyUSB0,raw,echo=0,baud=115200,crnl SYSTEM:"while read line; do echo \"\$line\"; done > /tmp/dsmr_pipe"
- 启动两个socat实例分别转发到不同TCP端口:
socat TCP-LISTEN:12345,reuseaddr,fork OPEN:/tmp/dsmr_pipe,rdonly socat TCP-LISTEN:12346,reuseaddr,fork OPEN:/tmp/dsmr_pipe,rdonly
该方法通过read line确保每次转发的都是完整报文,彻底避免边界错位问题。
方案3:优化ftee的缓冲策略
如果坚持使用ftee,需强制其按行缓冲输出,收到CR+LF时立即刷新缓冲区:
stdbuf -oL cat /dev/ttyUSB0 | ftee /tmp/fifo-1 /tmp/fifo-2
stdbuf -oL将标准输出设为行缓冲,保证每收到完整报文就立即写入管道。同时启用ser2net的两个连接配置:
connection: &meter1 accepter: tcp,12345 enable: on connector: file(infile=/tmp/fifo-1) connection: &meter2 accepter: tcp,12346 enable: on connector: file(infile=/tmp/fifo-2)
内容的提问来源于stack exchange,提问作者Jan Ceuleers
相关产品推荐
相关产品推荐

