如何在Ruby中读取UDP广播数据报

时间:2018-01-26 15:36:18

标签: ruby sockets udp datagram

我在Google上搜索了很多,甚至在Stackoverflow上也找不到解决问题的方法。我能够创建一个可以侦听给定端口的服务器。

require 'socket'
listenPort = 1001
ss = UDPSocket.new()
ss.bind('', listenPort) #listen all IPs 
while true do
  p ss.recvfrom(2000)
end
ss.close

我能够在同一个Vlan上创建一个在计算机上发送消息的客户端:

require 'socket'
listenPort = 1001
sc = UDPSocket.new
cpt = 0
5.times do
  cpt += 1
  sc.send("Hello #{cpt}", 0, "100.64.212.151", listenPort)
end
sc.close

即使使用需要sudo的1001端口在linux上运行良好,所有工作都很好。但我需要在计算机上读取/接收来自程序(使用1001端口)的数据包。

我知道我的服务器在听:

$ netstat -n --udp --listen | grep 1001
> udp    0   0 0.0.0.0:1001     0.0.0.0:*

使用Wireshark,我知道消息到达服务器监听的计算机上:

> N° Time   Source          Destination  protocol Length Info  
> 1  0.OOO  100.64.212.150  225.1.1.1    UDP      639    54672->1001 Len 597
> Internet Protocol Version 4, Src: 100.64.212.150, Dst: 225.1.1.1
> User Datagram Protocol, Src Port: 54672, Dst Port: 1001
> Data (597 bytes)

但是我的简单服务器从来没有看到任何东西,除非我用自己的客户端发送的消息。我不知道如何使用Ruby(或过度语言Java,PHP ..)执行Wireshark所能做的事情。我明白Wireshark的运行水平非常低,但我并不了解我应该做些什么让我的服务器监听我正在寻找的数据包。

1 个答案:

答案 0 :(得分:1)

我犯了一个错误。这不是广播的问题,而是处理多播的问题。

对于多播,您必须注册您的服务器才能收听。我在github.com/jpignata/blog/blob/master/articles/multicast-in-ruby.md找到了解释。所以在绑定之前要添加两行:

membership = IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new(BIND_ADDR).hton
s.setsockopt(:IPPROTO_IP, :IP_ADD_MEMBERSHIP, membership)

为此你必须:

require 'ipaddr'

并定义MULTICAST_ADDR ='225.1.1.1'和BIND_ADDR ='0.0.0.0'(或=''')

服务器变为:

require 'socket'
require 'ipaddr'

listenPort = 1001
MULTICAST_ADDR = '225.1.1.1'
BIND_ADDR = '0.0.0.0'

s = UDPSocket.new
membership = IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new(BIND_ADDR).hton
s.setsockopt(:IPPROTO_IP, :IP_ADD_MEMBERSHIP, membership)
s.bind BIND_ADDR, listenPort
while true do
  p ss.recvfrom(2000)
end
ss.close