Обновить членство в многоадресной группе
У меня есть несколько встроенных машин, которые прослушивают и транслируют аудиоданные rtp в многоадресную группу. Они подключены к интеллектуальному управляемому коммутатору (Netgear GS108Ev2), который выполняет базовое отслеживание igmp и многоадресную фильтрацию на своих портах, так что остальная часть моей (W) локальной сети не будет заполнена.
При запуске все отлично работает около 500-520 секунд. После этого они не получают больше данных, пока не покинут группу и снова не присоединятся к группе. Я думаю, что переключатель "забывает" о соединении после тайм-аута.
Есть ли способ обновить членство в группе, то есть сообщить коммутатору, что все еще кто-то слушает, не теряя пакеты?
Системная информация:
Arch: blackfin
# cat /proc/version
Linux version 2.6.28.10-ADI-2009R1-uCBF54x-EMM
(gcc version 4.3.3 (ADI) ) #158 PREEMPT Tue Jun 5 20:05:42 CEST 2012
3 ответа
Так работает многоадресная передача / протокол IGMP. Клиент должен периодически присоединяться к группе, отправляя отчет о членстве, или предполагается, что он покинул группу после некоторого короткого перерыва. Однако эти отчеты обычно отправляются только при получении запроса на членство от локального многоадресного маршрутизатора. Либо ваши клиенты не получают запрос, либо не отвечают сообщением.
Попробуйте использовать такой инструмент, как wireshark, чтобы увидеть, какие пакеты IGMP отправляются через вашу сеть.
Вам нужен IGMP-запрос для отправки Membership Queries
, как уже объяснили Scai.
Если вы не можете настроить маршрутизатор для этого, вы можете использовать один из ваших компьютеров. Видя, что запуск полного демона многоадресной маршрутизации был бы излишним (а я никогда этого не делал), я предлагаю вам попытаться использовать igmpproxy.
Сначала создайте фиктивный восходящий интерфейс (это не является постоянным!):
ip tap add dev tap6 mode tap
Напишите igmpproxy.conf:
# Dummy upstream interface.
phyint tap6 upstream ratelimit 0 threshold 1
# Local interface.
phyint eth0 downstream ratelimit 0 threshold 1
# Explicitly disable any other interfaces (yes, it sucks).
phyint NAME disabled
...
Наконец, запустите igmpproxy (как root):
igmpproxy -v /path/to/igmpproxy.conf
Если ваши встроенные устройства работают под управлением Linux, вам нужно отключить обратный фильтр пакетов на них, иначе они не будут отвечать на запросы членства в группах. В этом случае вышестоящий коммутатор будет предполагать, что никто не слушает эту многоадресную рассылку, и выключит ее.
У меня была такая же проблема, многоадресная передача по Wi-Fi была потеряна через 260 секунд, я решил ее с помощью своего приложения, добавив AddSourceMembership в сокет.
private void StartListner(IPAddress sourceIp, IPAddress multicastGroupIp, IPAddress localIp, int port)
{
try
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint localEndpoint = new IPEndPoint(localIp, port);
socket.Bind(localEndpoint);
byte[] membershipAddresses = new byte[12]; // 3 IPs * 4 bytes (IPv4)
Buffer.BlockCopy(multicastGroupIp.GetAddressBytes(), 0, membershipAddresses, 0, 4);
Buffer.BlockCopy(sourceIp.GetAddressBytes(), 0, membershipAddresses, 4, 4);
Buffer.BlockCopy(localIp.GetAddressBytes(), 0, membershipAddresses, 8, 4);
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, membershipAddresses);
try
{
byte[] b = new byte[1024 * 2];
int length = socket.Receive(b);
}
catch { }
}
catch (Exception ex)
{
logger.Error("Exception: " + ex);
}
}