检查插座是否在bash中关闭?

时间:2011-07-06 09:23:58

标签: linux bash sockets shell

我有一个指向套接字的文件描述符(下面是示例代码)。

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

有时候套接字会关闭,需要重新打开(重启服务器)。

如何测试套接字(在这种情况下为fd#3)是否可写?

无论套接字是否已经关闭,回声总是会成功。

5 个答案:

答案 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

答案 1 :(得分:3)

已经有一段时间了,因为op发布了这个,所以他们可能看不到这个,但它可能会帮助其他人。

无论如何,我正在研究这个问题,我找到了以下内容。

进程的open 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之间消失。然而,到目前为止,所有解决方案都适用。

答案 2 :(得分: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 :(得分:0)

您可以使用netstat命令grep获取所需的端口/地址,然后使用cut状态字段。请注意,在连接丢失后的一段时间内,套接字可能会显示为“ESTABLISHED”,特别是如果您没有向其发送任何数据。

答案 4 :(得分:0)

尝试写入fd:

if ! echo some text >&3;
  then echo The port is closed >&2
fi

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