Bash TCP 重定向传输结束

Bash TCP 重定向传输结束

我使用 xinetd 制作了一个简单的网络服务,它从 tcp 套接字读取字符串并输出其编码视图。原始二进制文件(qrencode)只是读取标准输入。

netcat当我与as一起使用时效果很好echo string | nc <ip> <port>

但当我尝试通过 bash tcp 重定向使用它时,它没有回答。

exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7

它永远等待。我尝试将 \004, cat /dev/null 回显到此 fd,但没有成功。我怎样才能让它发挥作用?

答案1

inetd服务或您的服务可能正在等待 EOF,然后退出(然后关闭连接)。

为此,您需要客户端关闭套接字的发送端,同时仍保持接收端打开。这就是nc当它在标准输入上检测到 EOF 时所做的事情。

/dev/tcp/host/port的虚拟接口(bash从 ksh 复制而来)不允许这样做。即使zshztcp更灵活的替代方案,也无法非对称地关闭连接。

您可以依靠超时来代替,但那是不可靠的。因此,最好继续依赖像nc或 这样的专用实用程序socat(可能使用 coproc 来拥有类似的接口),或者使用具有适当网络 API 的编程语言(带有 的接口shutdown())。

^D当行规则处于icanon模式时(实现粗略的行编辑器),0x04 字符 ( ) 仅表示终端设备的 EOF。因此,为了使其工作,您必须在xinetd您的服务创建的套接字之间插入一个伪终端。例如,通过以下方式启动:

socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3

代替

your-service

然后你需要发送:

printf 'text\n\4' >&7

或者:

printf 'text\4\4' >&7

让您的服务看到输入的结尾。

由于该行编辑器,your-service仅当您发送换行符或字符时才会看到输入^D(我们已禁用所有其他编辑字符,例如上面的werase, erase, ,kill并且^C, ^Z... 处理也作为 的一部分被禁用raw)。

因此,您不妨插入一个输入预处理器,而不是在 0x4 字符处退出,例如:

awk -v RS='\4' -v ORS= '{print; exit}' | your-service

(请注意,只要没有收到完整的缓冲区或 eof,awk就不能mawk坚持不处理其输入)。mawk

答案2

看来,如果您的服务没有关闭已建立的 TCP 会话,那么除了停止客户端连接之外没有其他方法。例如使用超时命令:

timeout 1 cat <&7

echoing \004, cat /dev/null此外,您尝试的其他命令 ( ) 很可能会失败,因为您是从另一个 shell 执行这些命令的。请注意,文件描述符 7 附加到执行第一个 shell 的 shell exec 7<>/dev/tcp/<ip>/<port>,因此您只能从第一个 shell 中与其交互。

参考

相关内容