2011-07-06 65 views
6

我有一个指向套接字的文件描述符(下面的示例代码)。检查套接字是否在bash中关闭?

exec 3<>/dev/tcp/localhost/9999 
echo -e "Some Command\n" >&3 

有时该套接字关闭并需要重新打开(重新启动服务器)。

如何测试套接字(本例中为#3)是否可写?

无论套接字是否已经关闭,echo都会始终成功。

+0

你想知道它是否可写_ **或** _it是否关闭_?第一个是权限问题,后者是状态问题。这些只是稍有关系(有效的文件模式可能会受到开放标志的影响,如果您愿意,可以将其称为_state_) – sehe

+0

@sehe这不是权限问题。他在谈论插座。没有与套接字相关的写权限。如果您可以打开套接字,您可以阅读并写入它。 – EJP

+0

特别是如果它关闭。我知道它是可写的,我可以在正常情况下打开套接字,但是当我断开连接(网络问题,服务器在脚本运行时关闭等)时,我需要尝试在继续之前重新打开它。 –

回答

4

解决方案是来自服务器的反馈。

当您向服务器发送请求时,它需要回答它。

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 
+0

不错的想法,不幸的是,它是一个没有反馈的单向馈送。 –

+0

在这种情况下,也许使用netcat来确定端口是否打开? – bbaja42

+0

你也可以在列表中添加“telnet”。我并不真正宽容使用telnet,但我记得在没有/ dev并且没有netcat的旧系统上使用它。 –

0

可以使用netstat命令,grep,然后cut只是状态字段。请注意,连接丢失后,套接字可能会显示为“ESTABLISHED”一段时间,特别是如果您未向其发送任何数据。

0

尝试写FD:

请注意,我不建议写多余的数据来检验,如果文件描述符 仍然是有效的,但我建议你只是试图写入任何数据 你想要的,然后检查它的工作。如果写入失败,请重新打开 套接字并重新写入。

1

我会添加自己的最终解决方案(以简洁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。这样,在检查套接字是否打开(还有一些棘手的问题)和实际写入(在检查它打开后可能仍然失败)之间没有任何时间间隔。

3

自从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之间消失。然而,迄今为止所有解决方案都适用。

相关问题