为什么需要在bash中使用文件描述符来返回UDP或TCP流量?



我知道需要使用文件描述符才能从TCP或UDP套接字读取。例如:

exec 3<>/dev/udp/192.0.2.1/161; echo -n "302902010104067075626c6963a01c02047f14ec98020100020100300e300c06082b060102010105000500" | xxd -r -p >&3; read -n 1 -t 0.2 <&3

但是,为什么不能直接从套接字中读取呢?例如:

echo -n "302902010104067075626c6963a01c02047f14ec98020100020100300e300c06082b060102010105000500" | xxd -r -p > /dev/udp/192.0.2.1/161; read -n 1 -t 0.2 < /dev/udp/192.0.2.1/161

套接字是可以在两个方向上使用的单个文件描述符。在Bash、<>中,通常的文件操作符只能在一个方向上操作一个文件描述符。

您可以覆盖现有的描述符,如stdin,然后显式地使用该文件描述符号。但这基本上等同于使用一个单独的描述符。

如果你这样做:

echo -n "$hex_string" | xxd -r -p > /dev/udp/192.0.2.1/161
read -n 1 -t 0.2 < /dev/udp/192.0.2.1/161

结果将是UDP套接字将使用一些临时端口(如42297)打开到端口161发送,然后消息将被写入端口161,然后套接字将被关闭。随后,另一个UDP套接字将使用不同的临时源端口(如48546)向端口161打开,然后脚本将等待该套接字上的输入。在侦听端,将从端口42297接收一个数据包,并且假定也向端口42297发送一个响应。但是客户端没有监听端口42297;根据发送响应的速度,它可能正在监听端口48546,也可能没有,但是服务器端无法知道这一点。

对于TCP,情况与此类似,而且更清晰一些,但同样无用。echo命令建立一个TCP连接,发送一些数据,然后关闭连接。服务器端将收到数据包,然后立即收到断开指示,因此它将无法回复。

使用第一个示例,其中打开连接并将其分配给文件描述符,套接字将不会关闭,直到echoread都完成(以及在该shell中处理的任何其他命令)。使用持久套接字,不存在通信问题。

相关内容

  • 没有找到相关文章

最新更新