我有一个指向套接字的文件描述符(下面的示例代码)。检查套接字是否在bash中关闭?
exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
有时该套接字关闭并需要重新打开(重新启动服务器)。
如何测试套接字(本例中为#3)是否可写?
无论套接字是否已经关闭,echo都会始终成功。
我有一个指向套接字的文件描述符(下面的示例代码)。检查套接字是否在bash中关闭?
exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
有时该套接字关闭并需要重新打开(重新启动服务器)。
如何测试套接字(本例中为#3)是否可写?
无论套接字是否已经关闭,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
不错的想法,不幸的是,它是一个没有反馈的单向馈送。 –
在这种情况下,也许使用netcat来确定端口是否打开? – bbaja42
你也可以在列表中添加“telnet”。我并不真正宽容使用telnet,但我记得在没有/ dev并且没有netcat的旧系统上使用它。 –
可以使用netstat
命令,grep
,然后cut
只是状态字段。请注意,连接丢失后,套接字可能会显示为“ESTABLISHED”一段时间,特别是如果您未向其发送任何数据。
尝试写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。这样,在检查套接字是否打开(还有一些棘手的问题)和实际写入(在检查它打开后可能仍然失败)之间没有任何时间间隔。
自从op发布这篇文章以来,他们可能不会看到这个,但它可能会帮助其他人。
无论如何,我正在调查这个问题,我发现以下。
进程的开放fd(文件描述符)列在/ proc // 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之间消失。然而,迄今为止所有解决方案都适用。
你想知道它是否可写_ **或** _it是否关闭_?第一个是权限问题,后者是状态问题。这些只是稍有关系(有效的文件模式可能会受到开放标志的影响,如果您愿意,可以将其称为_state_) – sehe
@sehe这不是权限问题。他在谈论插座。没有与套接字相关的写权限。如果您可以打开套接字,您可以阅读并写入它。 – EJP
特别是如果它关闭。我知道它是可写的,我可以在正常情况下打开套接字,但是当我断开连接(网络问题,服务器在脚本运行时关闭等)时,我需要尝试在继续之前重新打开它。 –