使用管道和 UDP 的 Netcat/socat 行为?

sda*_*aau 18 udp netcat pipe socat

我想这很接近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]]
Run Code Online (Sandbox Code Playgroud)

 

这就是我觉得奇怪的地方:第一种情况按预期工作 - 我在一个终端中打开了一个 UDP 服务器:

$ sudo nc -ul 5000
Run Code Online (Sandbox Code Playgroud)

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

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C
Run Code Online (Sandbox Code Playgroud)

……再回到服务器端hello,按预期打印了三遍:

$ sudo nc -ul 5000 
hello
hello
hello
^C
Run Code Online (Sandbox Code Playgroud)

 

到目前为止一切顺利,一切都按预期进行。但是,假设我现在通过管道输入到客户端来尝试相同的方法;所以首先在一个终端中建立一个UDP服务器:

$ sudo nc -ul 5000
Run Code Online (Sandbox Code Playgroud)

...在另一个中,将一些数据nc作为 UDP 客户端通过管道传输:

$ echo hello | nc -u 127.0.0.1 5000
hello
hello
^C
Run Code Online (Sandbox Code Playgroud)

...在客户端命令之后,shell 有点像在等待输入一样冻结 - 所以我在那里输入hello和 ENTER 两次;但是服务器只注册了第一个hello(通过管道传输echo)。此外,即使您按 Ctrl-C 并尝试重复客户端echo hello | nc -u 127.0.0.1 5000命令,服务器仍将继续只报告第一个hello

$ sudo nc -ul 57130 
hello
^C
Run Code Online (Sandbox Code Playgroud)

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

 

nc是应该的行为方式吗?我希望至少echo hello | nc -u 127.0.0.1 5000会注册重复调用- 无需重新启动服务器?或者对于这种行为可能有一个特殊的命令行开关?

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

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发送单词之后存在- 然而,同样,在服务器重新启动之前,连续运行此命令不会在服务器上引起任何接收。

sda*_*aau 27

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

$ socat - udp4-listen:5000,reuseaddr,fork
Run Code Online (Sandbox Code Playgroud)

...然后,在另一个终端中,我们可以在命令行上多次调用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
Run Code Online (Sandbox Code Playgroud)

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

$ socat - udp4-listen:5000,reuseaddr,fork
hello
hello
hello
^C
Run Code Online (Sandbox Code Playgroud)

 

请注意,即使使用fork-edsocat服务器,该行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
Run Code Online (Sandbox Code Playgroud)

... fork-edsocat服务器将显示三个hellos 而无需重新启动..

 

看起来,这个 openBSDnetcat没有fork选项 - 但我不确定它是否有与之对应的选项。

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