【问题标题】:Check whether socket is closed in bash?检查套接字是否在bash中关闭?
【发布时间】:2012-03-09 05:51:13
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 您想知道它是否可写 是否已关闭?第一个是权限问题,后者是状态问题。这些只是稍微相关(有效的文件模式会受到打开标志的影响,如果你愿意,可以将其称为 state
  • @sehe 这不是权限问题。他在谈论套接字。没有与套接字关联的写权限。如果您可以打开套接字,则可以读取和写入。
  • 特别是如果它已关闭。我知道它是可写的,我可以在正常情况下打开套接字,但是当我失去连接时(网络问题、脚本运行时服务器关闭等)我需要尝试重新打开它才能继续。跨度>

标签: linux bash sockets shell


【解决方案1】:

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

当您向服务器发送请求时,它需要对其进行响应。

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来确定端口是否打开?
  • 您不妨将“telnet”添加到列表中。我并不真正容忍使用 telnet,但我记得在没有 /dev 和 netcat 的旧系统上使用它。
【解决方案2】:

自从 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 之间消失。但是,到目前为止,这适用于所有解决方案。

【讨论】:

    【解决方案3】:

    我将添加我自己的最终解决方案(以简洁的伪代码):

    { 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 无法处理标准输入上的数据,它将选择将其写入缓冲区文件并尝试重新启动 netcat。这样,您在检查套接字是否打开(这仍然很棘手)和实际写入(在检查它是否打开后可能仍然失败)之间没有任何时间段。

    【讨论】:

      【解决方案4】:

      您可以使用netstat 命令,grep 用于您想要的端口/地址,然后cut 只是状态字段。请注意,在连接丢失后的一段时间内,套接字可能会显示为“已建立”,特别是在您没有向其发送任何数据的情况下。

      【讨论】:

        【解决方案5】:

        尝试写入 fd:

        如果 !回显一些文本 >&3; 然后 echo 端口关闭 >&2 菲

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-06
          • 1970-01-01
          • 2019-09-01
          相关资源
          最近更新 更多