如何实现nc与socat在Linux同一TCP端口1234上并行监听处理数据?
如何实现nc与socat在Linux同一TCP端口1234上并行监听处理数据?
兄弟,你碰到的是个典型的TCP端口绑定限制——同一时间一个TCP端口只能被一个进程独占监听,所以直接开两个nc/socat分别抢1234端口,肯定会有一个抢不到,就算侥幸启动了也收不到数据。
核心思路很简单:用一个「主监听进程」占住1234端口,然后把收到的数据复制分流给两个处理逻辑(也就是你要的文件写入和MQTT转发)。下面给你两个用你熟悉的工具就能实现的方案:
方案一:用tee+命名管道分流(最易上手)
这个方案靠Linux的命名管道和tee命令,把主进程收到的数据同时传给两个后续处理步骤:
- 先创建两个命名管道(相当于进程间通信的“中转通道”,用起来和普通文件一样):
mkfifo /tmp/tcp_to_socat /tmp/tcp_to_nc
- 启动主监听的socat进程,负责接端口数据并分流到两个管道:
nohup socat -u TCP4-LISTEN:1234,reuseaddr,fork,bind=192.168.13.1 EXEC:'tee /tmp/tcp_to_socat /tmp/tcp_to_nc' &
这里的fork参数必须加,它会为每个新的TCP连接创建独立子进程,保证多个客户端同时发数据也能正常处理;tee的作用就是把输入的数据原封不动复制到两个管道里,让两个处理逻辑都能拿到完整数据。
- 分别启动两个处理进程:
- 负责写入文件的逻辑(替代你原来的socat文件写入命令):
nohup cat /tmp/tcp_to_socat >> /out_socat.txt &
- 你的MQTT转发逻辑(现在从管道读数据,不用再监听端口):
nohup cat /tmp/tcp_to_nc | wmbusmeters --selectfields=total_m3 --shell='/usr/bin/mosquitto_pub -h 192.168.15.20 -t licznik_glowny/water -m "$METER_JSON" -u mqtt_user -P mqtt_user' stdin:rtlwmbus licznik_glowny apatorna1 04913581 NOKEY &
方案二:用socat直接多目标转发(更简洁)
如果不想折腾命名管道,也可以让socat直接把数据同时发送到文件和wmbusmeters进程,用socat内置的TEE地址类型一步到位:
nohup socat -u TCP4-LISTEN:1234,reuseaddr,fork,bind=192.168.13.1 TEE:"OPEN:/out_socat.txt,creat,append" EXEC:'wmbusmeters --selectfields=total_m3 --shell=\"/usr/bin/mosquitto_pub -h 192.168.15.20 -t licznik_glowny/water -m \\\"$METER_JSON\\\" -u mqtt_user -P mqtt_user\" stdin:rtlwmbus licznik_glowny apatorna1 04913581 NOKEY' &
这个命令让socat监听端口后,把每个连接的数据同时写入/out_socat.txt,并直接传给wmbusmeters处理,省去了中间的管道和cat命令,不过要注意内部引号的转义(比如把"$METER_JSON"转义成\\\"$METER_JSON\\\")。
注意事项
- 启动新进程前,一定要先杀掉之前跑的socat/nc进程,避免端口冲突:
pkill socat && pkill nc - 可以查看
nohup.out文件排查启动问题,比如权限不足、管道不存在之类的错误 - 命名管道如果后续不用了,等进程都停了再用
rm /tmp/tcp_to_socat /tmp/tcp_to_nc删除
备注:内容来源于stack exchange,提问作者Krzysiek




