管道和UDP的Netcat / socat行为?


16

我想这已经接近Linux了-Netcat停止监听UDP流量-超级用户,但我还是想问一问

至于netcat的版本,我使用的是Ubuntu 11.04及其默认版本,netcat我猜是这样的openbsd

$ nc
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
      [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [hostname] [port[s]]

 

我发现这很奇怪:第一种情况按预期工作-我在一个终端中打开UDP服务器:

$ sudo nc -ul 5000

...,然后在另一个终端中,我启动一个新的UDP客户端连接-并键入hello3次,每次输入后按Enter:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

...并返回到服务器终端,它已hello按预期打印了三遍:

$ sudo nc -ul 5000 
hello
hello
hello
^C

 

到目前为止,一切正常。但是,假设我现在通过将输入传递到客户端来尝试相同的操作。因此,首先在一个终端中建立一个UDP服务器:

$ sudo nc -ul 5000

...,然后将一些数据通过管道nc作为UDP客户端:

$ echo hello | nc -u 127.0.0.1 5000
hello
hello
^C

...在执行客户机命令之后,shell会冻结,好像在等待输入一样-因此在这里我hello再输入两次ENTER;但服务器仅注册了第一个hello(通过管道传输echo)。此外,即使你按下Ctrl-C,并尝试重复客户端echo hello | nc -u 127.0.0.1 5000命令,服务器将仍然保持在具有报道只是第一个hello

$ sudo nc -ul 57130 
hello
^C

...并且只有在使用Ctrl-C停止服务器并再次重新启动服务器之后,才能重复执行客户端echo hello | nc -u 127.0.0.1 5000命令并观察其工作情况。

 

nc是应该表现的方式吗?我希望至少会重复echo hello | nc -u 127.0.0.1 5000注册,而不必重新启动服务器?或者,也许有一种特殊的命令行开关用于这种行为?

编辑:我发现了一个不错的PDF演示文稿:socat –处理所有类型的套接字,其中包含以下netcatvs socat注释:

netcat-局限性
●仅可一次性执行(在套接字关闭后终止)
...
示例1:netcat替换
...•
具有源端口的UDP客户端:
nc -u -p 500 1.2.3.4 500
socat-udp:1.2.3.4: 500,sp = 500
●TCP服务器:
nc -l -p 8080
socat-tcp-l:8080,reuseaddr
...

...但是,如果我将服务器命令替换为socat - udp4-listen:5000,reuseaddr“-”,将客户端命令替换为“ ... ” ,则我将获得与上述相同的行为socat - udp:127.0.0.1:5000……通过管道输入“ echo hello | socat - udp:127.0.0.1:5000”,唯一的区别是在这里,该命令至少在hello发送单词后存在-但是,再次运行该命令将不会导致服务器接收任何信息,直到重新启动服务器为止。

Answers:


23

好的,我认为至少我了解到一些东西socat-即,该选项fork需要附加到服务器行:

$ socat - udp4-listen:5000,reuseaddr,fork

...然后,在另一个终端中,我们可以在命令行上多次调用echo管道到socat客户端行,因为它将立即退出(好吧,半秒钟之后:)):

$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000

...并回到第一个终端,我们可以看到服务器已成功显示所有三个hellos:

$ socat - udp4-listen:5000,reuseaddr,fork
hello
hello
hello
^C

 

请注意,即使使用fork-ed socat服务器,该行echo "hello" | nc -u 127.0.0.1 5000仍将“锁定”,就像等待用户输入一样。但是,现在在Ctrl-C之后重新运行命令,即

$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C

... fork-ed socat服务器将显示三秒,hello而无需重新启动。

 

看来,这个openBSD netcat没有fork选项-但是我不确定它是否具有与其对应的选项。

无论如何,希望这对某人有帮助,
干杯!


4

当您使用管道时,您的netcat仅从echo的stdout读取输出,它不再与键盘“连接”。要获得期望的响应,可以将三个“ hello”添加到运行文件中

cat [myfile] | nc -u 127.0.0.1 5000

嗨@OldWolf-非常感谢您的回答!我尝试了您的建议(也以某种更复杂的方式“ cat $(echo -e "hello\nhello\nhello\n" > tmpf; echo tmpf) | nc -u 127.0.0.1 5000”),但是,尽管我确实看到了3 hellos,但仍然令我感到困惑的是:该命令也将“锁定”,就像等待来自输入的输入一样。用户,并且在Ctrl-C并重新运行它之后,服务器将不会看到任何数据,除非重新启动它!那就是我想更好地了解的-干杯!
sdaau's

2
nc正在等待EOF,在这种情况下,直到您将退出信号发送给程序,该命令才会生效。
OldWolf 2011年

啊,我明白了-非常感谢您的解释,@ OldWolf!似乎socat可以使用该fork选项解决此问题...再次感谢,加油!
sdaau 2011年

3

如果对侦听的nc进行跟踪,它将显示netcat正在等待连接,一旦连接成功,它将连接到该主机和端口,而忽略所有其他连接。您需要添加“ -k”以继续进行操作,并添加“ -w 0”以在0秒后使每个连接超时。我认为Socat是更好的选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.