我有一个文件描述符指向一个套接字(下面的例子代码)。
exec 3<>/dev/tcp/localhost/9999 echo -e "Some Command\n" >&3
有时该套接字closures,需要重新打开(重新启动服务器)。
如何testing套接字(本例中是#3)是否可写?
无论套接字是否已经closures,echo都将始终成功。
解决方案是来自服务器的反馈。
当你发送一个请求到服务器,它需要回答它。
exec 3<>/dev/tcp/localhost/9999 echo -e "Some Command\n" >&3 sleep 5 # example max time given to server to respond cat <&3 #receive an answer check is correct, restart server otherwise
编辑:使用netcat来确定端口是否打开
netcat -w 3 -z www.google.com 80 if[ $? -eq 0 ] then echo port open else echo port closed fi
自从op发布以来,已经有一段时间了,所以他们可能不会看到这个,但它可能会帮助其他人。
无论如何,我正在研究这个问题,我发现以下几点。
/ proc // fd下列出了一个进程的开放fd(文件描述符)。
exec 3<>/dev/tcp/localhost/9999 #check if still connected if [ $(ls /proc/$$/fd | grep -w "3") == 3 ]; then #send data echo -e "Some Command\n" >&3 else #perform reconnect exec 3<>/dev/tcp/localhost/9999 fi
这没有测试,但应该是大多好。 可能还有一些改进。 还有一个窗口,fd在你的支票和写给fd之间消失。 然而,迄今为止所有的解决方案。
我将添加我自己的最终解决方案(在简短的psudo代码):
{ while true; read file; write to STDOUT } | { while true; netcat command; write STDIN to buffer when/if netcat exits; loop to restart netcat & first process buffered data if exists; }
这将数据输出(文件读取)和数据处理(在没有套接字可用时将其发送到套接字或缓冲到文件)分离。 当网络问题发生时,它使用管道提供临时缓冲区。
第二代码块的STDIN缓冲来自第一代码块的输出。 如果netcat无法处理stdin上的数据,它将选择将其写入缓冲区文件并尝试重新启动netcat。 这样,在检查套接字是否打开(还有一些棘手的问题)和实际写入(在检查打开后可能仍然失败)之间没有任何时间间隔。
你可以使用netstat
命令, grep
作为你想要的端口/地址,然后只cut
状态字段。 请注意,连接丢失后,套接字可能会显示为“ESTABLISHED”一段时间,特别是如果您没有向其发送任何数据。
尝试写入fd:
如果! 回显一些文字>&3; 然后回显该端口关闭>&2 科幻
请注意,我并不是建议编写多余的数据来测试文件描述符是否仍然有效,但是建议您只是简单地尝试写任何你想要的数据,然后检查它是否工作。 如果写入失败,请重新打开套接字并重新写入。