在多宿主 Windows 10 台机器上接收 UDP 多播消息
Receiving UDP Multicast Messages on a Multihomed Windows 10 Machine
我有一个 C# .NET 客户端侦听 UDP 多播消息。我需要在单个网络接口上接收消息。有时我看不到收到的消息。当我禁用其他接口时,它可以工作。
我尝试使用本站点上类似问题的代码将套接字选项设置为特定接口,但是,我不确定这是否只影响发送多播消息而不影响接收它们?
经过研究,我发现路由 table 导致了此行为,一种解决方案是更改路由 table,但我不想走那条路。
是不是所有接口都加入多播组比较好?我将如何使用 UdpClient.
来做到这一点
这是用于设置我的 UdpClient 的代码:
获取接口:
public static IEnumerable<NetworkInterface> GetAvailableMulticastInterfaces()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
List<NetworkInterface> availableInterfaces = new List<NetworkInterface>();
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
availableInterfaces.Add(adapter);
}
return availableInterfaces;
}
设置接口:
NetworkInterface networkInterface = Common.Utilities.Network.GetAvailableMulticastInterfaces().Where(nic => nic.Id == attributes.SelectedNetworkInterfaceId).FirstOrDefault();
获取接口索引:
networkInterfaceIndex = (int)IPAddress.HostToNetworkOrder(networkInterface.GetIPProperties().GetIPv4Properties().Index);
绑定 UdpClient:
public void Listen(string multicastGroupAddress, int port, int? networkInterfaceIndex = null)
{
IpAddress = multicastGroupAddress;
Port = port;
_multicastEndPoint = new IPEndPoint(IPAddress.Parse(multicastGroupAddress), port);
Listener = new UdpClient();
Listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
if (networkInterfaceIndex != null)
Listener.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, networkInterfaceIndex.Value);
var localEndpoint = new IPEndPoint(IPAddress.Any, port);
Listener.Client.Bind(localEndpoint);
Listener.JoinMulticastGroup(IPAddress.Parse(multicastGroupAddress));
while (true)
Process();
}
好的,所以我回到这里并找到了正确的操作。必须使用
加入多个接口
var availableMulticastNics = Utils.GetAvailableMulticastInterfaces();
var listener = new UdpClient();
listener.Client.Bind(new IPEndPoint(IPAddress.Any, endpoint.Port));
foreach (var ni in availableMulticastNics)
{
listener.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastEndPoint.Address, ni.GetIPProperties().GetIPv4Properties().Index));
}
// Ready to read socket
而不是 listener.JoinMulticastGroup(ni.GetIPProperties().GetIPv4Properties().Index, multicastEndPoint.Address)
。否则,我会得到一个 SocketException,告诉我无效的参数,如果可以的话,有人可以解释一下。
我有一个 C# .NET 客户端侦听 UDP 多播消息。我需要在单个网络接口上接收消息。有时我看不到收到的消息。当我禁用其他接口时,它可以工作。
我尝试使用本站点上类似问题的代码将套接字选项设置为特定接口,但是,我不确定这是否只影响发送多播消息而不影响接收它们?
经过研究,我发现路由 table 导致了此行为,一种解决方案是更改路由 table,但我不想走那条路。
是不是所有接口都加入多播组比较好?我将如何使用 UdpClient.
来做到这一点这是用于设置我的 UdpClient 的代码:
获取接口:
public static IEnumerable<NetworkInterface> GetAvailableMulticastInterfaces()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
List<NetworkInterface> availableInterfaces = new List<NetworkInterface>();
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
availableInterfaces.Add(adapter);
}
return availableInterfaces;
}
设置接口:
NetworkInterface networkInterface = Common.Utilities.Network.GetAvailableMulticastInterfaces().Where(nic => nic.Id == attributes.SelectedNetworkInterfaceId).FirstOrDefault();
获取接口索引:
networkInterfaceIndex = (int)IPAddress.HostToNetworkOrder(networkInterface.GetIPProperties().GetIPv4Properties().Index);
绑定 UdpClient:
public void Listen(string multicastGroupAddress, int port, int? networkInterfaceIndex = null)
{
IpAddress = multicastGroupAddress;
Port = port;
_multicastEndPoint = new IPEndPoint(IPAddress.Parse(multicastGroupAddress), port);
Listener = new UdpClient();
Listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
if (networkInterfaceIndex != null)
Listener.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, networkInterfaceIndex.Value);
var localEndpoint = new IPEndPoint(IPAddress.Any, port);
Listener.Client.Bind(localEndpoint);
Listener.JoinMulticastGroup(IPAddress.Parse(multicastGroupAddress));
while (true)
Process();
}
好的,所以我回到这里并找到了正确的操作。必须使用
加入多个接口var availableMulticastNics = Utils.GetAvailableMulticastInterfaces();
var listener = new UdpClient();
listener.Client.Bind(new IPEndPoint(IPAddress.Any, endpoint.Port));
foreach (var ni in availableMulticastNics)
{
listener.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastEndPoint.Address, ni.GetIPProperties().GetIPv4Properties().Index));
}
// Ready to read socket
而不是 listener.JoinMulticastGroup(ni.GetIPProperties().GetIPv4Properties().Index, multicastEndPoint.Address)
。否则,我会得到一个 SocketException,告诉我无效的参数,如果可以的话,有人可以解释一下。