我在同一 LAN 上的两台联网 Linux 机器上有两个应用程序。运行一个服务器程序,该程序侦听指定端口上的 TCP 连接,并在连接时发出(但不接收)数据。不同机器上的客户端程序侦听 TCP 连接,并且在连接时期望接收服务器发送的数据(但本身不发出任何数据)。
到目前为止,我一直在使用nc server1 30000 | nc client1 29999
或socat -u TCP:server1:30000 TCP:client1:29999
,但是,一旦网络连接失败,无论使用哪种解决方案,该过程都不会结束,也不会自动重新连接。
有没有一种优雅的方法来做到这一点?
早些时候我考虑过多播;即让服务器通过网络多播数据,但这需要每台计算机上的上述命令之一来终止数据流,并且可能最终会出现相同的问题。
该连接仅传输少量数据;当然远远不足以使带宽或 CPU 饱和。
答案1
我认为真正可靠的解决方案是用 C (或 python 或 perl)编写一些小应用程序。一般来说,您可能首先检查是否连接失败或传输时间过长。第二件事是检查您从服务器获得了多少数据以及发送/接收数据需要多长时间。如果出现问题,请重试。
在 bash 中,您可以检查是否连接失败或未使用 nc 退出代码。
根据您的环境限制,在 bash 中检查超时可能很棘手 - 如果可以安装timeout
它应该很容易。如果没有,你仍然可以用纯 bash 写一些东西。
如果您的远程服务器在发送数据后断开连接,您可以检查接收时间是否比某些时间长,这将更加可控。
如果您可以先在中间主机上接收所有数据,然后再连接客户端,这也可能很容易。
就像是:
loop for some acceptable amount of retries
connect server
if connect failed continue
save data to buffer
if connection close and not enough data continue
if timeout happened interrupt and continue
now if we got data do other loop
connect client
if connect failed continue
send buffer
if timeout happened interrupt and continue (this is only acceptable if your client is OK to receive data multiple times)
如何在 bash 中执行上述操作(注意 - 我没有真正测试所有内容,因此可能需要进行细微更改):
for ((attempt = 0; attempt < 10; attempt++)); do
BUFFER=$(timeout 10 nc server1 port1) || continue
[ ${#BUFFER} -ge 1 ] || continue
for ((client_attempt = 0; client_attempt < 10; client_attempt++)); do
echo "$BUFFER" | timeout 10 nc client2 port2 || continue
done
break
done
答案2
我最终在 while(true) 循环中使用了nmap
's ,如下所示:ncat
/bin/bash -c while true; do ncat -i 50s --recv-only remotehost 12345 | ncat -i 50s --send-only localhost 12346; sleep 10; done
50 秒超时后,每个进程都会结束,while 循环将重新生成它们。