netcat 与 UDP 的奇怪行为

发布于 2024-12-08 22:44:45 字数 534 浏览 4 评论 0原文

我注意到使用 netcat 和 UDP 时出现了奇怪的行为。我启动了一个监听 UDP 端口的 netcat 实例(实例 1):

nc -lu -p 10000

因此,我启动了另一个 netcat 实例(实例 2)并尝试将数据报发送到我的进程:

nc -u 127.0.0.1 10000

我看到了数据报。但是,如果我关闭实例 2 并再次重新启动 netcat(实例 3):

nc -u 127.0.0.1 10000

我在实例 1 的终端上看不到数据报。显然,操作系统在实例 3 上相对于实例 2 分配了不同的 UDP 源端口,问题就在那里:如果我使用相同的实例 2 源端口(例如 50000):

 nc -u -p 50000 127.0.0.1 10000

netcat 的实例 1 再次接收数据报。 UDP 是一种无连接协议,那么为什么呢?这是标准的 netcat 行为吗?

I noticed a strange behaviour working with netcat and UDP. I start an instance (instance 1) of netcat that listens on a UDP port:

nc -lu -p 10000

So i launch another instance of netcat (instance 2) and try to send datagrams to my process:

nc -u 127.0.0.1 10000

I see the datagrams. But if i close instance 2 and relaunch again netcat (instance 3):

nc -u 127.0.0.1 10000

i can't see datagrams on instance 1's terminal. Obsiously the operating system assigns a different UDP source port at the instance 3 respect to instance 2 and the problem is there: if i use the same instance'2 source port (example 50000):

 nc -u -p 50000 127.0.0.1 10000

again the instance 1 of netcat receives the datagrams. UDP is a connection less protocol so, why? Is this a standard netcat behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ゝ偶尔ゞ 2024-12-15 22:44:45

当 nc 正在侦听 UDP 套接字时,它会“锁定”其收到的第一个数据包的源端口和源 IP。查看此跟踪:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f\n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

在这里您可以看到它创建了一个 UDP 套接字,将其设置为地址重用,并将其绑定到端口 10,000。一旦它收到第一个数据报(来自端口 52,832),它就会发出 connect 系统调用,将其“连接”到 127.0.0.1:52,832。对于 UDP,connect 会拒绝所有与 connect 中的 IP 和端口不匹配的数据包。

When nc is listening to a UDP socket, it 'locks on' to the source port and source IP of the first packet it receives. Check out this trace:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f\n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

Here you can see that it created a UDP socket, set it for address reuse, and bound it to port 10,000. As soon as it received its first datagram (from port 52,832), it issued a connect system call 'connecting' it to the 127.0.0.1:52,832. For UDP, a connect rejects all packets that don't match the IP and port in the connect.

家住魔仙堡 2024-12-15 22:44:45

使用 -k 选项:

nc -l -u -k 0.0.0.0 10000
  • -k 表示保持活动状态,netcat 在每次连接后保持监听
  • -u 表示 UDP
  • -l 监听端口 10000

Use the -k option:

nc -l -u -k 0.0.0.0 10000
  • -k means keep-alive, that netcat keeps listening after each connection
  • -u means UDP
  • -l listening on port 10000
长亭外,古道边 2024-12-15 22:44:45

在我的操作系统版本上放弃了 netcat 之后,这很短并且完成了工作:

#!/usr/bin/ruby
# Receive UDP packets bound for a port and output them
require 'socket'
require 'yaml'

unless ARGV.count == 2
  puts "Usage: #{$0} listen_ip port_number"
  exit(1)
end
listen_ip = ARGV[0]
port = ARGV[1].to_i

u1 = UDPSocket.new
u1.bind(listen_ip, port)
while true
  mesg, addr = u1.recvfrom(100000)
  puts mesg
end

Having given up on netcat on my OS version this is pretty short and gets the job done:

#!/usr/bin/ruby
# Receive UDP packets bound for a port and output them
require 'socket'
require 'yaml'

unless ARGV.count == 2
  puts "Usage: #{$0} listen_ip port_number"
  exit(1)
end
listen_ip = ARGV[0]
port = ARGV[1].to_i

u1 = UDPSocket.new
u1.bind(listen_ip, port)
while true
  mesg, addr = u1.recvfrom(100000)
  puts mesg
end
染柒℉ 2024-12-15 22:44:45

正如已接受的答案所解释的,ncat 似乎不支持 UDP 协议的 --keep-open。但是,它打印的错误消息暗示了解决方法:

Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING.

只需添加 --exec /bin/cat 即可使用 --keep-open 。输入和输出都将连接到 /bin/cat,其效果是将其变成“回显服务器”,因为客户端发送的任何内容都将被复制回它。

要对输入执行更有用的操作,我们可以使用 shell 的重定向运算符(因此需要 --sh-exec 而不是 --exec)。要查看终端上的数据,可以这样做:

ncat -k -l -u -p 12345 --sh-exec "cat > /proc/$/fd/1"

注意:上面的示例将数据发送到 ncat 的 父 shell 的标准输出,如果与其他重定向结合使用,这可能会造成混乱。将所有输出简单地附加到文件中更简单:

ncat -k -l -u -p 12345 --sh-exec "cat >> ncat.out"

As the accepted answer explains, ncat appears not to support --keep-open with the UDP protocol. However, the error message which it prints hints at a workaround:

Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING.

Simply adding --exec /bin/cat allows --keep-open to be used. Both input and output will be connected to /bin/cat, with the effect of turning it an "echo server" because whatever the client sends will be copied back to it.

To do something more useful with the input, we can use the shell's redirection operators (thus requiring --sh-exec instead of --exec). To see the data on the terminal, this works:

ncat -k -l -u -p 12345 --sh-exec "cat > /proc/$/fd/1"

Caveat: the above example sends data to the stdout of ncat's parent shell, which could be confusing if combined with additional redirections. To simply append all output to a file is more straightforward:

ncat -k -l -u -p 12345 --sh-exec "cat >> ncat.out"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文