nc 在 OS X 上不等待服务器断开连接

nc 在 OS X 上不等待服务器断开连接

如何使ncOS X Mavericks 上的客户端保持套接字打开并读取数据,直到服务器断开套接字?

我想通过将数据发送到服务器nc,然后使用响应。问题是nc在发送数据后断开套接字,而不等待服务器的响应。

这只会写入数据然后退出:

$ echo "my instruction here" | nc 127.0.0.1 $MY_PORT

这将写入数据,然后即使服务器已断开连接也不会退出:

$ cat <(echo "my instruction here") - | nc 127.0.0.1 $MY_PORT

OS X Mavericks 上的手册页nc有以下用于发送HTTP GET请求和打印响应的示例,但它不起作用。它只是发送请求然后退出,而不等待服务器的响应。手册页的信息似乎不正确?

$ echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80

答案1

nc 的默认行为是在 stdin 关闭时关闭连接。要进行更改,您可以在 Linux 上使用 -q 选项(如-q -1),在 OS X 上可能是相同的。有关详细信息,请参阅手册页。

编辑:看起来 OS X nc 不支持 -q 开关或类似的东西。在这种情况下,您需要通过执行以下操作来确保 stdin 不会关闭:

(回显“foo”;睡眠100000)|数控...

答案2

一旦监听nc(服务器)关闭,客户端nc也会退出。

在 Mac OS X 上,您可以open -a 'Activity Monitor'验证这一点。

该示例挂起的原因nc & cat不是nc,而是cat继续保持其 stdin 和 stdout 打开以供读取和写入。

但是,当在监听关闭cat后尝试写入管道时,会引发并终止。ncSIGPIPEcat

# cat & SIGPIPE test
(sleep 1; echo hi) | 
   (trap 'echo "received signal $(($? - 128))" 1>&2' EXIT; cat) | :

kill -l 13
man bash | less -p 'EXIT STATUS'
man bash | less -Ip '128\+n'

作为 Niklas Berglund 解决方法的替代方案,可以捕获客户端退出nc以杀死整个进程组,包括挂起cat命令。

# console 1
# ctrl-c will "kill 0" entire process group sh -c '...'
nc -l 8080  

# console 2
# script command (FreeBSD version) will implicitly run: man 2 setsid
# kill 0 will therefore only kill the entire process group sh -c '...' 
# run in a script kill 0 would otherwise kill the entire script
# cf. also https://github.com/jerrykuch/ersatz-setsid 
script -q /dev/null sh -c '
(echo "my instruction here"; cat) | (trap "kill 0" EXIT; nc 127.0.0.1 8080)
'

答案3

解决方法是继续向套接字写入内容 - 一旦无法写入数据nc就会退出。

(echo -ne "GET / HTTP/1.0\r\n\r\n"; (while true; do echo -e "\n"; sleep 1; done)) | nc example.com 80

nc这将每秒发送一次空行,直到nc无法写入套接字并nc退出。

感谢 Steffen Ullrich 的回答和评论指导我找到了这个解决方案。

相关内容