UdpClient在连接时不接收多播流量

时间:2015-10-27 20:00:50

标签: c# windows udp multicast

我使用UdpClient来接收和发送多播流量,但是当应用程序启动并运行时新的网络接口开始运行时,我遇到了问题。

当接口运行时,我的应用程序中创建UdpClient(插入网络电缆引发NetworkChange.NetworkAddressChanged),它绑定到接口的静态IP,并且可以看到预期的IGMP数据包该接口上的wireshark,但UdpClient实例从不报告有任何数据可用。

如果在连接电缆之前创建UdpClient,问题似乎也会出现。

我已尝试设置SocketOptionName.MulticastInterface,但这只会涉及发送多播流量,而不是接收...此处的示例:https://support.microsoft.com/en-us/kb/318911

这是一个展示此问题的控制台应用。当这个应用程序运行时,我连接以太网电缆,Wireshark显示来自此应用程序的IGMP加入组数据包,以及来自另一台计算机的传入多播流量。如果我已经插入电缆并启动应用程序,它将收到我期望的所有流量。

class Program
{
    static UdpClient udpClient;

    static IPAddress bindAddress = IPAddress.Parse("192.168.101.220");
    static IPAddress groupListenAddress = IPAddress.Parse("239.255.0.1");
    static int port = 9999;

    static bool shouldRun = true;
    static Thread thread;

    static void Main(string[] args)
    {
        udpClient = new UdpClient();
        udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true);

        IPEndPoint localEndPoint = new IPEndPoint(bindAddress, port);
        udpClient.Client.Bind(localEndPoint);

        udpClient.JoinMulticastGroup(groupListenAddress);

        thread = new Thread(runThread);
        thread.Start();

        Console.WriteLine("Press Enter to exit.");
        Console.ReadLine();

        shouldRun = false;
        thread.Join(100);
    }

    private static void runThread(object obj)
    {
        while (shouldRun)
        {
            if (udpClient.Available > 0)
            {
                IPEndPoint endPoint = null;
                byte[] buffer = udpClient.Receive(ref endPoint);
                Console.WriteLine("Received Message from: {0} Length: {1}", endPoint, buffer.Length);
            }
            Thread.Sleep(10);
        }

    }
}

1 个答案:

答案 0 :(得分:1)

Note that IGMP messages are sent by your host OS, not by your application. If the OS sees a join for a multicast address for the first time it will send out IGMP messages. If another process wants to join the same address as well, new IGMP message may or may not be sent. Also all kinds of network components (in particular routers, but also Powerline adapters use IGMP snooping to find out where to send multicast traffic, and they often get it wrong. There are two incompatible versions of IGMP and some devices support only one version and some translate between versions in a strange way. This is a big mess. To make it all really horrible, most devices, including your local host OS, have a time dependent behavior. This makes analyzing problems really difficult since you can never draw hard conclusions, because at the moment it may work just by chance. Independent of IGMP, the bind() statement is confusing for UDP. On Linux bindign to an IP address will filter all incoming UDP packets and you will only receive packets going to this specific IP address. To receive multicast traffic on Linux you usually have to bind to 0.0.0.0. But I assume you are using Windows, where binding to an IP address of a local adapter is the right thing. Then you will receive mutilcast traffic going to this adapter.