netcat与UDP的奇怪行为

时间:2011-10-08 12:40:18

标签: networking udp netcat

我注意到使用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 个答案:

答案 0 :(得分:40)

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和端口不匹配的数据包。

答案 1 :(得分:5)

使用 -k 选项:

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

答案 2 :(得分: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

答案 3 :(得分:0)

如已接受的答案所解释,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,从而将其变成“回显服务器”,因为客户端发送的任何内容都将被复制回它。

要对输入做更多有用的事情,我们可以使用外壳程序的重定向运算符(因此需要--sh-exec而不是--exec)。要在终端上查看数据,此方法有效:

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

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

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