bash 检查套接字是否在bash中关闭?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6594159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check whether socket is closed in bash?
提问by David Parks
I've got a file descriptor that points to a socket (example code below).
我有一个指向套接字的文件描述符(下面的示例代码)。
exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
Sometimes that socket closes and needs to be re-opened (a restart of the server).
有时该套接字关闭并需要重新打开(重新启动服务器)。
How can I test if the socket (fd #3 in this case) is writable?
如何测试套接字(在本例中为 fd #3)是否可写?
The echo will always succeed, regardless of whether the socket has been closed already or not.
无论套接字是否已经关闭,echo 总是会成功。
采纳答案by bbaja42
Solution is the feedback from the server.
解决方案是来自服务器的反馈。
When you send a request to the server, it needs to answer to it.
当您向服务器发送请求时,它需要响应它。
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
EDIT: using netcat to determine is the port is open
编辑:使用 netcat 确定端口是否打开
netcat -w 3 -z www.google.com 80
if[ $? -eq 0 ]
then
echo port open
else
echo port closed
fi
回答by BenAnderson
It has been awhile since op posted this so they might not see this but it might help someone else.
op 发布这个已经有一段时间了,所以他们可能看不到这个,但它可能会帮助其他人。
Anyway I was looking into this very issue and I found the following.
无论如何,我正在研究这个问题,我发现了以下内容。
The open fd's (file descriptors) of a process are listed under /proc//fd.
进程的打开 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
This wasn't tested but should be mostly ok. Might be some improvements as well. Also there is a window where the fd goes away between your check and the writing to fd. However that goes for all solutions so far.
这没有经过测试,但应该基本没问题。可能还有一些改进。还有一个窗口,fd 在您的支票和写入 fd 之间消失。但是,这适用于迄今为止的所有解决方案。
回答by David Parks
I will add my own final solution (in terse psudo-code):
我将添加我自己的最终解决方案(简洁的伪代码):
{ 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; }
This separates the output of data (the reading of a file) and the processing of the data (sending it to a socket or buffering to a file when no socket is available). It uses the pipe to provide a temporary buffer when network issues occur.
这将数据的输出(读取文件)和数据的处理(将其发送到套接字或在没有套接字可用时缓冲到文件)分开。当发生网络问题时,它使用管道提供临时缓冲区。
The STDIN of the second code block buffers the output from the first codeblock. If netcat is unable to process data on stdin it will opt to write that out to a buffer file and try to re-start netcat. This way you don't have any period of time between checking that socket is open (something that's still tricky) and the actual write (which might still fail after checking that it's open).
第二个代码块的 STDIN 缓冲第一个代码块的输出。如果 netcat 无法处理 stdin 上的数据,它将选择将其写入缓冲区文件并尝试重新启动 netcat。这样,您在检查套接字是否打开(仍然很棘手)和实际写入(在检查它已打开后可能仍然失败)之间没有任何时间段。
回答by Vitor
You can use the netstatcommand, grepfor the port/address you want, and then cutjust the state field. Please note that a socket may appear as "ESTABLISHED" for some time after the connection is lost, specially if you aren't sending any data to it.
您可以将netstat命令grep用于所需的端口/地址,然后cut仅使用状态字段。请注意,在连接丢失后的一段时间内,套接字可能会显示为“已建立”,特别是如果您没有向其发送任何数据。
回答by William Pursell
Try writing to the fd:
尝试写入 fd:
if ! echo some text >&3; then echo The port is closed >&2 fi
Note that I'm not suggesting writing superfluous data to test if the file descriptor is still valid, but am suggesting that you simply try to write whatever data you want and then check that it worked. If the write failed, reopen the socket and write again.
请注意,我并不是建议编写多余的数据来测试文件描述符是否仍然有效,而是建议您尝试编写所需的任何数据,然后检查它是否有效。如果写入失败,则重新打开套接字并再次写入。

