netcat与UDP的奇怪行为

时间:2021-08-16 13:50:41

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

我注意到netcat和UDP有一种奇怪的行为。我启动一个netcat实例(实例1),它监听UDP端口:

nc -lu -p 10000

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

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

nc -u 127.0.0.1 10000

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

我看到了数据报。但是如果我关闭实例2并重新启动netcat(实例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):

我在实例1的终端上看不到数据报。显而易见,操作系统在实例2的实例3上分配了一个不同的UDP源端口,问题是:如果我使用相同的实例2源端口(示例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?

netcat的实例1再次接收数据报。UDP是一个没有连接的协议,为什么?这是一种标准的网络猫行为吗?

3 个解决方案

#1


39  

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:

当nc监听UDP套接字时,它会“锁定”到它接收到的第一个包的源端口和源IP。看看这个跟踪:

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

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

#2


5  

Use the -k option:

使用- k选项:

nc -l -u -k 0.0.0.0 10000
  • -k means keep-alive, that netcat keeps listening after each connection
  • -k的意思是保持活力,netcat每次连接后都在监听
  • -u means UDP
  • - u意味着UDP
  • -l listening on port 10000
  • -我在10000港口听。

#3


2  

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

在我的OS版本上放弃了netcat,这很短,并且完成了任务:

#!/usr/bin/ruby# Receive UDP packets bound for a port and output themrequire 'socket'require 'yaml'unless ARGV.count == 2  puts "Usage: #{$0} listen_ip port_number"  exit(1)endlisten_ip = ARGV[0]port = ARGV[1].to_iu1 = UDPSocket.newu1.bind(listen_ip, port)while true  mesg, addr = u1.recvfrom(100000)  puts mesgend

#1


39  

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:

当nc监听UDP套接字时,它会“锁定”到它接收到的第一个包的源端口和源IP。看看这个跟踪:

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

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

#2


5  

Use the -k option:

使用- k选项:

nc -l -u -k 0.0.0.0 10000
  • -k means keep-alive, that netcat keeps listening after each connection
  • -k的意思是保持活力,netcat每次连接后都在监听
  • -u means UDP
  • - u意味着UDP
  • -l listening on port 10000
  • -我在10000港口听。

#3


2  

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

在我的OS版本上放弃了netcat,这很短,并且完成了任务:

#!/usr/bin/ruby# Receive UDP packets bound for a port and output themrequire 'socket'require 'yaml'unless ARGV.count == 2  puts "Usage: #{$0} listen_ip port_number"  exit(1)endlisten_ip = ARGV[0]port = ARGV[1].to_iu1 = UDPSocket.newu1.bind(listen_ip, port)while true  mesg, addr = u1.recvfrom(100000)  puts mesgend