В настоящее время я использую Ruby 1.8.7 для разработки Linux-версии инструмента для Windows, который проверяет многоадресные данные на двух интерфейсах на основе настроенных пользователем многоадресных групп и портов.
У меня была предыдущая проблема, когда я не знал, как слушать несколько многоадресных каналов, но это было решено с помощью предыдущего вопроса.
Это привело к следующей проблеме. Мне нужно слушать несколько многоадресных групп и:
Определите, были ли получены какие-либо данные по каждой из конкретных групп, и сообщите, какие из них имеют данные, а какие нет.
Слушайте данные в течение настраиваемого пользователем периода времени ожидания на всех каналах одновременно.
Я пытаюсь заставить это работать в отдельном фрагменте кода, где многоадресные группы, порты и интерфейсы жестко закодированы, как только я разберусь и пойму, я перенесу его в свою основную программу, где пользовательский ввод и проверка уже завершены . Я обновил свой простой программный код, и теперь он выглядит так:
#!/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, поскольку в этом сокете есть 2 группы многоадресной рассылки
Как одновременно отслеживать настраиваемое количество групп многоадресной рассылки для данных и не допустить, чтобы одна ошибка при получении данных приводила к выводу неправильной ошибки