Linux netcat 监听器(nc -l)挂起

Linux netcat 监听器(nc -l)挂起

在我的 Raspberry Pi 3 终端(Linux)上,我输入了以下内容并点击Enter

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/' | nc -l 2345

Raspberry Pi 3 是我家庭网络的一部分,固定地址为 192.168.0.8。然后,我在 Mac 上的浏览​​器 (Chrome) 中输入以下内容并点击Enter

192.168.0.8:2345

我可以在我的 Linux 终端(Raspberry Pi)上看到浏览器的 GET 请求,但是nc监听器卡住了并且没有将答复(HTTP 302 重定向消息)发送到浏览器。

仅当我nc通过点击Ctrl+停止程序时C,浏览器才会收到回复消息并显示https://www.eff.org网站。

有谁知道为什么nc监听器卡住了而不是发送答复并关闭连接?

答案1

我复制了您的问题。当我使用另一个nc浏览器而不是浏览器进行连接时,我看到回复正在立即发送。我认为您的浏览器也收到了回复,但由于nc没有终止连接,浏览器不知道这一切,因此可以继续重定向。

\r\n(注意:在我的测试中,我需要回复中的最后一个nc才能成功重定向我的浏览器,因此我所有的示例都使用此修复程序。)


编辑:简单修复

这里我发现了以下情况:

HTTP 请求和 HTTP 响应使用 RFC 822 的通用消息格式来传输所需的数据。该通用消息格式由以下四项组成。

  • [...]
  • [...]
  • 一个空行(即 CRLF 之前没有任何内容的行),表示标头字段的结束
  • [...]

所以你的答复应该是:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n\r\n' | ...

收到此信息后,您的浏览器应继续重定向,自行终止连接nc。2017 年 12 月初,它适用于 Opera 和 Vivaldi;但不适用于 Firefox、Chrome 或 Safari,您可能需要其他修复程序(见下文)。



原来的,现在较差的答案(对于非 HTTP 通信可能仍然有用nc

根据Server Fault 上的这个答案您需要使用-c-q类似选项,具体取决于nc实施。

在我的 Debian 中,我-q安装了可用的版本。然后

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -q 0 -l -p 2345

工作正常(注意我还需要-p指定端口)。解释如下:

-q seconds
EOFon 后stdin,等待指定的秒数然后退出。如果秒数为负数,则永远等待(默认)。


如果你nc没有合适的选择,那么解决方法可能是检测来自客户端的通信并终止整个命令行。在我的 Debian 中可以运行的一个示例bash是:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -l -p 2345 | { read foo; sleep 1; kill 0; }

运行管道时,bash将每个进程放在一个进程组中;kill 0向其整个进程组发送信号。此方式nc在收到触发的任何请求后约 1 秒内被终止read

相关内容