首页 文章

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

提问于
浏览
-1

我正在使用 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 回答

  • 1

    请注意,IGMP消息由主机操作系统发送,而不是由您的应用程序发送 . 如果操作系统第一次看到多播地址的连接,它将发送IGMP消息 . 如果另一个进程也想加入相同的地址,则可能会或可能不会发送新的IGMP消息 .

    此外,所有类型的网络组件(特别是路由器,以及电力线适配器使用IGMP监听来找出发送多播流量的位置,并且它们经常出错 . 有两个不兼容的IGMP版本,有些设备只支持一个版本,有些以一种奇怪的方式在版本之间进行转换 . 这是一个很大的混乱 .

    为了使这一切变得非常可怕,大多数设备(包括本地主机操作系统)都具有时间依赖性 . 这使得分析问题真的很困难,因为你无法得出可靠的结论,因为目前它可能只是偶然的 .

    与IGMP无关,bind()语句对UDP来说是混乱的 . 在Linux上绑定到IP地址将过滤所有传入的UDP数据包,您将只接收发往此特定IP地址的数据包 . 要在Linux上接收多播流量,通常必须绑定到0.0.0.0 . 但我假设您使用的是Windows,其中绑定到本地适配器的IP地址是正确的 . 然后,您将收到进入此适配器的多播流量 .

相关问题