Как присоединиться к нескольким многоадресным группам на одном интерфейсе

У меня есть доступная версия Ruby 1.8.7, и ее нельзя обновить, поскольку она является частью стандартного образа, который в настоящее время используется на всех серверах Linux компаний, и все, что я делаю, должно работать на всех этих серверах. без проблем (я надеюсь, что это не будет проблемой)

Проект, который я делаю, заключается в воссоздании приложения, которое в настоящее время работает в Windows на сервере Linux. Приложение берет список многоадресных групп и интерфейсов и пытается присоединиться к группам, а затем прослушивает любые данные (неважно какие), сообщая, может ли оно присоединиться и есть ли данные. Это помогает нам в нашей среде проверить сетевое подключение до развертывания фактического программного обеспечения на сервере. Данные, которые он будет получать, будут представлять собой финансовую информацию с биржи в двоичном коде, поэтому мне не нужно выводить (отсюда закомментированная строка и вывод), мне просто нужно проверить, доступна ли она для сервера.

Я читал в Интернете и нашел фрагменты кода, которые я собрал вместе в небольшую версию этого, где он присоединяется к 1 группе многоадресной рассылки, привязанной к 1 интерфейсу, и прослушивает данные в течение определенного периода времени, сообщая, были ли какие-либо данные были получены.

Затем я хотел добавить вторую группу многоадресной рассылки, и здесь мне не хватает понимания того, как этого добиться. Мой код выглядит следующим образом:

#!/usr/bin/ruby

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

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

 ipA = IPAddr.new(MCAST_GROUP_A[:addr]).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
   sockA.setsockopt Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ipA
   sockA.setsockopt Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ipB
   sockA.bind Socket::INADDR_ANY, MCAST_GROUP_A[:port]
   sockA.bind Socket::INADDR_ANY, MCAST_GROUP_B[:port]

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

Ошибка, которую я получаю, когда запускаю это:

[root@dt1d-ddncche21a ~]# ./UDPServer.rb ./UDPServer.rb:35:in `setsockopt': Адрес уже используется (Errno::EADDRINUSE) из ./UDPServer.rb:35

Вот где я нахожусь и действительно мог бы сделать сначала указатели на то, что не так (надеюсь, с обновлением кода), а затем, как только я заработаю этот пример, следующим шагом будет добавление второго интерфейса в микс для прослушивания снова несколько многоадресных групп,


person Glen    schedule 01.07.2015    source источник
comment
Присоединение одного сокета к нескольким многоадресным группам не должно быть проблемой, однако сокет может одновременно связываться только с одним портом. Если вам нужно читать из нескольких портов, вам нужен отдельный сокет для каждого из них.   -  person dbush    schedule 01.07.2015
comment
Спасибо за ответ. Итак, как мне привязать несколько (а их может быть довольно много в зависимости от требований пользователя) сокетов к одному интерфейсу? Потенциально часть порта может быть такой же, но групповой адрес может измениться.   -  person Glen    schedule 01.07.2015
comment
Я делаю это так: сначала привязываю сокет к нужному порту, а затем вызываю setsockopt с IP_ADD_MEMBERSHIP для каждой группы, к которой я хочу присоединиться на этом порту. Я не слишком знаком с рубином, но так это делается через C API, и похоже, что функции более или менее совпадают.   -  person dbush    schedule 01.07.2015
comment
Итак, если у меня есть входной файл с группами многоадресной рассылки и портами, я должен сгруппировать все группы многоадресной рассылки, которые используют один и тот же порт вместе... привязать сокет к этому порту, а затем использовать setockopt IP_ADD_MEMBERSHIP для добавления групп. затем, как только я это сделаю, перейдите к следующему порту и повторите?   -  person Glen    schedule 01.07.2015
comment
Да, это должно сделать это.   -  person dbush    schedule 01.07.2015
comment
Хорошо, тогда я попробую и, возможно, вернусь с обновлением ... это может привести к большему количеству вопросов, которые, я думаю, будут лучше рассмотрены в новом посте.   -  person Glen    schedule 01.07.2015


Ответы (1)


Хорошо, поэтому я последовал совету, чтобы сначала привязаться к интерфейсу для каждого порта, а затем добавить участников для каждой из многоадресных групп, которые я хочу слушать, и это решило эту конкретную проблему и переместило меня к следующей проблеме, которая у меня есть. Следующий вопрос подниму как новую тему.

person Glen    schedule 01.07.2015