UdpClient没有';t在连接时接收多播流量

本文关键字:多播 流量 连接 没有 UdpClient | 更新日期: 2023-09-27 18:19:26

我使用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);
        }
    }
}

UdpClient没有';t在连接时接收多播流量

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

还有各种各样的网络组件(特别是路由器,还有电力线适配器)使用IGMP窥探来找出发送多播流量的位置,他们经常出错。IGMP有两个不兼容的版本,有些设备只支持一个版本,有些则以奇怪的方式在版本之间转换。这是一个大混乱。

更可怕的是,包括本地主机操作系统在内的大多数设备都有依赖时间的行为。这使得分析问题变得非常困难,因为你永远无法得出艰难的结论,因为目前它可能只是偶然的。

与IGMP无关,bind()语句对UDP来说是令人困惑的。在Linux上,绑定到一个IP地址将过滤所有传入的UDP数据包,并且您将只接收到此特定IP地址的数据包。要在Linux上接收多播流量,通常必须绑定到0.0.0.0。但我假设您使用的是Windows,绑定到本地适配器的IP地址是正确的。然后,您将收到流向此适配器的多播流量。