ruby - 如何同时监控多个组播组

标签 ruby linux udp multicast multicastsocket

我目前正在使用 Ruby 1.8.7 开发 Windows 工具的 Linux 版本,该工具根据用户配置的多播组和端口检查最多 2 个接口(interface)上的多播数据。

我之前遇到过一个问题,我不确定如何收听多个多播 channel ,但这已从之前的问题中得到解决。

这导致了下一个问题。我需要监听多个多播组并且:

  • 确定每个特定组是否收到任何数据,并报告哪些组有数据,哪些组没有数据

  • 同时在所有 channel 上监听用户可配置的超时期限的数据

我试图在一段单独的代码中实现这一点,其中多播组、端口和接口(interface)都是硬编码的,一旦我整理并理解了这一点,我将把它迁移到我的主程序,其中用户输入和验证已经完成。我已经更新了我的简单程序代码,现在它看起来像:

#!/usr/bin/ruby

require 'socket'
require 'ipaddr'
require 'timeout'

MCAST_GROUP_A
{
  :addr1 => '233.54.12.111',
  :addr2 => '233.86.230.111',
  :port => 26477,
  :bindaddr => '172.31.230.156'
}

MCAST_GROUP_B = 
{
  :addr => '233.54.12.111',
  :port => 18170,
  :bindaddr => '172.31.230.156'
}

ipA1 = IPAddr.new(MCAST_GROUP_A[:addr1]).hton + IPAddr.new(MCAST_GROUP_A[:bindaddr]).hton
ipA2 = IPAddr.new(MCAST_GROUP_A[:addr2]).hton + IPAddr.new(MCAST_GROUP_A[:bindaddr]).hton
ipB = IPAddr.new(MCAST_GROUP_B[:addr]).hton + IPAddr.new(MCAST_GROUP_B[:bindaddr]).hton

begin
  sockA = UDPSocket.open
  sockB = UDPSocket.open

  sockA.bind Socket::INADDR_ANY, MCAST_GROUP_A[:port]
  sockB.bind Socket::INADDR_ANY, MCAST_GROUP_B[:port]

  sockA.setsockopt Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ipA1
  sockA.setsockopt Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ipA2
  sockB.setsockopt Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ipB

  timeoutSeconds = 10
  Timeout.timeout(timeoutSeconds) do 
    msg1, info1 = sockA.recvfrom(1024)
    msg2, info2 = sockB.recvfrom(1024)
    #puts "MSG: #{msg} from #{info[2]} (#{info[3]})/#{info[1]} len #{msg.size}"
    puts "MSG: <garbled> from #{info1[2]} (#{info1[3]})/#{info1[1]} len #{msg1.size}"
    puts "MSG: <garbled> from #{info2[2]} (#{info2[3]})/#{info2[1]} len #{msg2.size}"
  end
  rescue Timeout::Error
    puts "Nothing received connection timedout\n"
ensure
  sockA.close
  sockB.close
end

但这产生了一个问题,因为它报告没有收到任何内容,因为 B 套接字上不存在数据。

我知道这样做的原因是第二个recvfrom超时,因此我们最终进入了代码的救援部分。但由于这是我的第一个 Ruby 程序,而且我仍在学习它,因此我不确定如何解决它。

简而言之,我需要了解:

  • 如何确定 sockA 在哪个 channel 上接收数据,因为该套接字上有 2 个多播组

  • 如何同时监控可配置数量的多播组的数据,并且不会因一次接收数据失败而导致输出不正确的错误

最佳答案

要同时监视多个套接字,请使用select函数。 This question给出了如何在 Ruby 中完成此操作的示例。

至少在 C 语言中,可以使用 IP_PKTINFO 套接字选项和 recvfrom 函数获取传入数据包的目标地址,但是 Ruby API 看起来并没有公开该功能。

关于ruby - 如何同时监控多个组播组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31180551/

相关文章:

ruby - 捕获小 cucumber 表中的尾随空格

Ruby/Rails 根据每个项目的相似性对数组进行排序

c - 使应用程序通过 UDP 相互发现

sockets - 带有 UDP 数据报的 SO_REUSEADDR - 资源不可用

类方法中的 Ruby 常量

ruby - 如何在 mac osx 上安装 libksba?

c - Linux C转储进程内存区域和搜索字符串问题

linux - 如何正确地从 Linux 内核 git 树中挑选有问题的提交

linux - 如何在不运行 source 命令的情况下将子 shell 的执行行打印到主 shell?

python - 尝试将 python 套接字绑定(bind)到 IPv6 地址时参数无效