在.NET中指定UDP多播应该使用的网络接口

在具有活动无线卡和LAN端口的计算机上,交叉电缆连接到运行相同应用程序的另一台计算机,我们需要通过LAN线将UDP多播发送到另一台计算机。 使用C#套接字,Windows似乎每次尝试通过WLAN适配器路由消息。

有没有办法指定发送UDP多播的网络接口?

您可能正在寻找SocketOptionName.MulticastInterface 。 这篇关于MSDN的文章可能会对你有所帮助。

除此之外,如果您更新本地路由表以获得与多播地址匹配的确切条目并指向正确的接口,那么它应该正常工作。

就像尼古拉的补遗一样:KB318911的问题是一个肮脏的伎俩,用户必须提供必要的适配器索引。 在查看如何检索此适配器索引时,我想出了这样的配方:

 NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adapter in nics) { IPInterfaceProperties ip_properties = adapter.GetIPProperties(); if (!adapter.GetIPProperties().MulticastAddresses.Any()) continue; // most of VPN adapters will be skipped if (!adapter.SupportsMulticast) continue; // multicast is meaningless for this type of connection if (OperationalStatus.Up != adapter.OperationalStatus) continue; // this adapter is off or not connected IPv4InterfaceProperties p = adapter.GetIPProperties().GetIPv4Properties(); if (null == p) continue; // IPv4 is not configured on this adapter // now we have adapter index as p.Index, let put it to socket option my_sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(p.Index)); } 

完整说明http://windowsasusual.blogspot.ru/2013/01/socket-option-multicast-interface.html

根据您正在做的事情,有一个可能有帮助的Win32方法。 它将返回给定IP地址的最佳接口。 要获得默认值(0.0.0.0),这通常是您想要的多播,它非常简单:

P / Invoke签名:

 [DllImport("iphlpapi.dll", CharSet = CharSet.Auto)] private static extern int GetBestInterface(UInt32 DestAddr, out UInt32 BestIfIndex); 

然后在其他地方:

 // There could be multiple adapters, get the default one uint index = 0; GetBestInterface(0, out index); var ifaceIndex = (int)index; var client = new UdpClient(); client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(ifaceIndex)); var localEndpoint = new IPEndPoint(IPAddress.Any, ); client.Client.Bind(localEndpoint); var multicastAddress = IPAddress.Parse(""); var multOpt = new MulticastOption(multicastAddress, ifaceIndex); client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt); var broadcastEndpoint = new IPEndPoint(IPAddress.Parse(""), ); byte[] buffer = ... await client.SendAsync(buffer, buffer.Length, broadcastEp).ConfigureAwait(false);