在 .NET 中指定 UDP 多播应进入哪个网络接口

发布于 2024-08-20 03:00:07 字数 164 浏览 10 评论 0原文

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

有没有办法指定在哪个网络接口上发送 UDP 多播?

On a computer with both an active Wireless Card and a LAN-Port with a crossover cable hooked up to another machine running the same application, we need to send a UDP multicast over the LAN wire to the other computer. Using C# Sockets, Windows seems to try to route the message over the WLAN adapter every time.

Is there a way to specify what network interface to send a UDP multicast on?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

多情癖 2024-08-27 03:00:07

正如尼古拉回答的附录: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

Just as addendum to Nikolai answer: the problem with KB318911 is a dirty trick that user must provide necessary adapter index. While looking how to retrieve this adapter index I figured out such recipe:

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));
}

Full note at http://windowsasusual.blogspot.ru/2013/01/socket-option-multicast-interface.html

墨小墨 2024-08-27 03:00:07

您可能正在寻找SocketOptionName.MulticastInterface这里是 MSDN 上的一篇文章,可能会对您有所帮助。

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

You are probably looking for SocketOptionName.MulticastInterface. Here's an article on MSDN that might help you.

Other then that if you update your local routing table to have an exact entry matching the multicast address and pointing to the right interface it should just work.

万劫不复 2024-08-27 03:00:07

根据您正在执行的操作,有一种 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, <port>);
client.Client.Bind(localEndpoint);

var multicastAddress = IPAddress.Parse("<group IP>");
var multOpt = new MulticastOption(multicastAddress, ifaceIndex);
client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt);

var broadcastEndpoint = new IPEndPoint(IPAddress.Parse("<group IP>"), <port>);
byte[] buffer = ...
await client.SendAsync(buffer, buffer.Length, broadcastEp).ConfigureAwait(false);

Depending on what you're doing, there's a Win32 method that might help. It'll return the best interface for a given IP address. To get the default one (the 0.0.0.0), which is usually what you want for multicast, it's pretty easy:

P/Invoke signature:

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

Then somewhere else:

// 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, <port>);
client.Client.Bind(localEndpoint);

var multicastAddress = IPAddress.Parse("<group IP>");
var multOpt = new MulticastOption(multicastAddress, ifaceIndex);
client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt);

var broadcastEndpoint = new IPEndPoint(IPAddress.Parse("<group IP>"), <port>);
byte[] buffer = ...
await client.SendAsync(buffer, buffer.Length, broadcastEp).ConfigureAwait(false);
骄傲 2024-08-27 03:00:07

如果您使用 UDPClient 类,则此方法会强制 IGMP 消息离开您想要的接口(第二个参数),即使绑定不起作用。

receiveUDPClient.JoinMulticastGroup(IPAddress.Parse("239.254.2.1"), IPAddress.Parse("192.168.6.1"));

否则,MulticastOption(IPAddress, IPAddress) 将起作用。第一个参数是多播地址,第二个地址强制使用您指定的本地端点。

If you are using UDPClient class, then this method forces the IGMP message out of the interface you desire (second parameter), even when binding doesn't work.

receiveUDPClient.JoinMulticastGroup(IPAddress.Parse("239.254.2.1"), IPAddress.Parse("192.168.6.1"));

Otherwise, MulticastOption(IPAddress, IPAddress) will work. The first parameter is the multicast address, the second address forces a localendpoint you specify to be used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文