【问题标题】:Overcoming network filtering issues when using UDP broadcast/multicast for simple service discovery使用 UDP 广播/多播进行简单的服务发现时克服网络过滤问题
【发布时间】:2021-06-29 14:51:06
【问题描述】:

我正在使用 C# 实现服务发现。为了解决一些问题,我实现了广播和多播,简化为所示的 sn-ps。

客户端广播:

var requestData = new byte[]{ /* Whatever */}

// Configure broadcast
var ipBroadcastEndPoint = new IPEndPoint(IPAddress.Broadcast, 12301);
var broadcastServerEp = new IPEndPoint(IPAddress.Any, 0);

var broadcastClient = new UdpClient {EnableBroadcast = true};
broadcastClient.Client.Bind(_broadcastServerEp);

// Send a request:
broadcastClient.Send(requestData, requestData.Length, ipBroadcastEndPoint);

// Listen for a reply:
var broadcastserverEp = new IPEndPoint(IPAddress.Any, 0);
var broadcastserverResponseData = broadcastClient.Receive(ref broadcastserverEp);

客户端多播:

var requestData = new byte[]{ /* Whatever */}

// Configure multicast
var ipMulticastEndPoint = new IPEndPoint(IPAddress.Parse("239.255.255.253"), 12302);
var multicastServerEp = new IPEndPoint(IPAddress.Any, 0);

var multicastClient = new UdpClient(AddressFamily.InterNetwork);
multicastClient.JoinMulticastGroup(IPAddress.Parse("239.255.255.253"), 32);
multicastClient.Client.Bind(_multicastServerEp);

// Send a request:
multicastClient.Send(requestData, requestData.Length, ipMulticastEndPoint);

// Listen for a reply:
var multicastserverEp = new IPEndPoint(IPAddress.Any, 0);
var multicastserverResponseData = multicastClient.Receive(ref multicastserverEp);

服务器端广播:

// Listen for broadcast
Task.Run(() =>
{
    var broadcastServer = new UdpClient(12301);
    while(/**/)
    {
        var broadcastclientEp = new IPEndPoint(IPAddress.Any, 0);
        var broadcastclientRequestData = broadcastServer.Receive(ref broadcastclientEp);

        // Reply to broadcast:
        var responseData = new byte[]{ /* Whatever */}
        broadcastServer.Send(responseData, responseData.Length, broadcastclientEp);
    }
}

服务器端多播:

// Listen for multicast
Task.Run(() =>
{
    var multicastServer = new UdpClient(12302);
    multicastServer.JoinMulticastGroup(IPAddress.Parse("239.255.255.253"));
    while(/**/)
    {
        var multicastclientEp = new IPEndPoint(IPAddress.Any, 0);
        var multicastclientRequestData = multicastServer.Receive(ref multicastclientEp);

        // Reply to multicast:
        var responseData = new byte[]{ /* Whatever */}
        multicastServer.Send(responseData, responseData.Length, multicastclientEp);
    }
}

如果客户端和服务器组件都在同一台计算机上运行,​​则广播和多播都按预期工作。

如果客户端和服务器组件位于同一子网中的不同计算机上,则广播工作,多播仅在一个方向上工作(给定 WLAN 拓扑中的两台计算机,当其中一台处于服务器角色时,多播工作,但不是反过来)。

如果客户端和服务器组件位于同一公司网络中的不同子网上,则广播或多播都不起作用。

我想让它跨子网可靠地工作。根据我目前了解到的情况,我知道广播不会起作用,但多播应该。

选择多播地址和/或端口号有什么魔力吗?换句话说,是否有特定的地址和端口我应该或不应该使用它来可靠地工作,而不管网络拓扑如何?是否存在通常被过滤或通常保持打开的地址/端口组合?有没有我忽略的配置选项?

【问题讨论】:

  • 组播并不意味着跨子网使用。问题是子网中有很多多播和广播消息。当您允许多播通过子网时,您最终会用这些消息淹没子网。子网由掩码定义。因此,仔细设计您的网络掩码可能会解决问题。您可能希望使用一个使用 TCP 或 UDP 连接子网并在子网之间转发特定多播消息的网桥。一些路由器具有限制允许在子网之间传递的多播消息的设置。
  • @jdweng 感谢您的信息。它确实让我想知道服务发现如何适用于软件产品许可证服务器或 LAN 被分成多个子网的打印机。它们是否仅在子网内工作,是否需要明确的路由器配置,还是使用 SLP 风格的广播/多播以外的其他技术?
  • 您正在创建一个多播网桥,您可以在该网桥上搜索。网桥的通用术语是端口转发,它是将消息从一个子网移动到另一个子网的通用术语。端口转发的类型取决于您需要转发的物理流量和流量(或不转发,以免网络泛滥)。如果您尝试从纽约转发到加利福尼亚,您将使用链接中的 Cisco 路由器。在同一个房间里,您可以只更改路由器上的设置来传递数据。端口转发可以通过软件或硬件来完成。
  • 只有广播消息会被路由器阻止。通常 IP 地址(或计算机名称)是硬编码的,不会被发现。在子网之外,使用使用 IP 地址和掩码的 IP 路由或使用 ARP 协议来查找子网之外的设备或服务器具有计算机列表的 DHCP。子网有一个网关,用作查找子网外设备的默认路由。网络就像一个树状结构,其中子网是叶子,网关通向根,即全球互联网。

标签: c# udp ip multicast


【解决方案1】:

允许多播流量在子网之间通过完全由这些子网之间的路由器控制。

路由器需要配置为使用静态多播路由,或者接受来自主机的 IGMP 消息以在它们加入时设置多播组。

【讨论】:

  • 路由器阻止多播,除非您特别设置路由器以允许多播 IP 通过。大多数路由器都有允许多播通过的设置。
猜你喜欢
  • 2014-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 2011-09-16
  • 2011-02-22
  • 1970-01-01
相关资源
最近更新 更多