我有一个指向套接字的文件描述符(下面是示例代码)。
exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
有时候套接字会关闭,需要重新打开(重启服务器)。
如何测试套接字(在这种情况下为fd#3)是否可写?
无论套接字是否已经关闭,回声总是会成功。
答案 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
请注意,我并不是建议编写多余的数据来测试文件描述符 仍然有效,但我建议您只是尝试编写任何数据 你想要,然后检查它是否有效。如果写入失败,请重新打开 套接字并再次写入。