我使用 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 复制而来)不允许这样做。即使zsh
是ztcp
更灵活的替代方案,也无法非对称地关闭连接。
您可以依靠超时来代替,但那是不可靠的。因此,最好继续依赖像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 中与其交互。