Refresh multicast group membership

只谈情不闲聊 提交于 2019-12-03 15:08:52

This is the way multicast / the IGMP protocol works. A client has to join the group periodically by sending a Membership Report or it will be assumed that he has left the group after some short timeout. However, those reports are usually sent only when receiving a Membership Query from the local multicast router. Either your clients don't receive the query or don't respond with a report.

Try to use a tool like wireshark in order to see which IGMP packets are sent through your network.

You need an IGMP querier to send the Membership Queries, as was already explained by scai.

If you can't configure your router to do that, you can use one of your computers. Seeing how running a full multicast routing daemon would be overkill (and I've never done that), I suggest you try to abuse igmpproxy.

First create a dummy upstream interface (this is not persistent!):

ip tap add dev tap6 mode tap

Write 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
...

Finally start igmpproxy (as root):

igmpproxy -v /path/to/igmpproxy.conf

If your embedded devices are running linux, you need to turn off the reverse packet filter on them or they won't respond to group membership queries. In that case the upstream switch will assume there is no-one listening to that multicast and switch it off.

I had same problem, multicast on wifi was lost after 260 seconds, I solved it with my application by adding AddSourceMembership on socket.

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);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!