36

我注意到与 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 行为吗?

4

4 回答 4

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,aconnect拒绝所有与connect.

于 2011-10-08T12:56:47.883 回答
4

使用-k选项:

nc -l -u -k 0.0.0.0 10000
  • -k 表示keep-alive,即netcat在每次连接后一直监听
  • -u 表示UDP
  • -l 监听 10000 端口
于 2015-03-01T11:42:37.563 回答
3

在我的操作系统版本上放弃了 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
于 2016-12-16T16:06:18.077 回答
1

正如接受的答案所解释的那样,ncat似乎不支持--keep-openUDP 协议。但是,它打印的错误消息提示了一种解决方法:

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"
于 2018-12-04T22:31:24.160 回答