我注意到使用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行为吗?
答案 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
答案 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"