【问题标题】:How to listen on multiple IP addresses?如何监听多个 IP 地址?
【发布时间】:2009-11-22 02:30:51
【问题描述】:

如果我的服务器分配了多个 IP 地址,并且我想收听其中的一些(或全部),我该怎么做?

是否需要为每个 IP 地址创建一个新的套接字并绑定它?我可以将多个 IP 地址绑定到单个套接字吗? IPAddress.Any 是否监听所有 IP 地址? MSDN 库在这个问题上非常不清楚。

【问题讨论】:

    标签: c# networking sockets


    【解决方案1】:

    您不能将单个套接字绑定到多个端点。 SocketException(无效参数错误)在您第二次为给定套接字调用 Bind() 时发生。

    正如其他人所说,您可以使用IPAddress.Any 来监听本地机器上的 IPv4 地址。但是,如果您只想侦听可用 IP 地址的子集,则必须创建单独的套接字。

    【讨论】:

    • 不,如果您只计算 IP v6 地址,IPAddress.Any 不会将 Socket 对象绑定到所有 IP 地址。正确的方法是创建两个 Socket 对象。然后一个绑定到 IPAddress.Any,另一个绑定到 IPAddress.IPv6Any。
    • 好点。我的项目仍然只是 IPv4,所以在我写答案时甚至没有考虑 IPv6。
    • var listener = new TcpListener(IPAddress.IPv6Any, Port); listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0); listener.Start(); @LexLi 这将帮助我创建两个(双堆栈)对吗?
    【解决方案2】:

    从技术上讲,您的服务器永远不会分配任何 IP 地址。

    相反,可以为各个网络接口分配 IP 地址。通常,每个 NIC 都有一个 IP 地址,但这只是最常见的情况。

    如果您想控制哪些接口正在侦听所选端口上的传入连接,则需要为每个接口创建一个单独的套接字。

    【讨论】:

    • 是的,我知道您为接口分配了 IP 地址,但 .NET 对您隐藏了它,您只需绑定到端点。我有点困惑,为什么您可以使用 IPAddress.Any 监听多个接口,但需要多个套接字来监听特定的。
    • 我怀疑这是框架设计者“让我们让常见案例易于实现”的案例,提供了一个有用的捷径。
    • Any 和 IPv6Any 可以被视为快捷方式。但是你不能要求一个框架为你提供你想要的所有快捷方式。我完全同意贝文的观点。当您更多地使用框架并开始设计自己的框架时,您会发现总是很难做出选择。
    • @ErikFunkenbusch 你找到你困惑的答案了吗?我也有同样的困惑。
    【解决方案3】:

    我已经研究过了,IPAddress.Any 不是正确的方法,它会绑定任何合适的 IP 地址。就我而言,我有 2 个 NIC,但我无法解决问题。当我添加时

    System.Net.IPAddress ipAddress = IPAddress.Parse("xxx.xxx.xxx.xxx");
    listener = new TcpListener(ipAddress, portNum);
    

    效果很好。

    【讨论】:

      【解决方案4】:

      如果您想监听所有 IPv4 和 IPv6 地址,请使用以下代码:

      var listener = new TcpListener(IPAddress.IPv6Any, port);
      listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
      

      IPv6Any 告诉 Windows 监听 IPv6 堆栈。将 socket 选项设置为 false 会告诉 Windows 不将自身限制在 IPv6 堆栈上,而是还要侦听 IPv4 堆栈。默认是只监听明确指定的栈。

      【讨论】:

      • 哇,真漂亮……嗯……不明显;)我认为这并不能证明有选择地收听多个 IP 的方法。
      • 这对大多数人来说可能无关紧要,但这仅在 .NET 4 或更高版本中受支持。
      【解决方案5】:

      是的,IPAddress.Any 将侦听所有接口。

      http://msdn.microsoft.com/en-us/library/system.net.ipaddress.any.aspx

      【讨论】:

      • 好的,这有帮助(Bind 方法只是说框架选择要监听的地址,这很模糊)。但是,如果我只想监听分配给计算机的 10 个 IP 地址中的 5 个呢?我需要5个插座吗?或者我可以使用不同的端点多次调用 Bind() 吗?
      • 是的,每个地址一个,除非您绑定到 Any 或 IPv6Any。
      【解决方案6】:

      MSDN 库在 IPAddress.Any 方面似乎确实矛盾。绑定文档

      http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind.aspx

      表示选择了“最合适”的地址,但 IPAddress.Any 文档

      http://msdn.microsoft.com/en-us/library/system.net.ipaddress.any.aspx

      表示使用此常量,套接字必须侦听所有接口上的活动。

      但是,有人告诉我这是 IPAddress。任何文档都是正确的。

      (添加这个作为答案,因为我没有足够的代表离开 cmets)。

      【讨论】:

        猜你喜欢
        • 2011-06-15
        • 2010-10-05
        • 2018-05-22
        • 2014-06-10
        • 2021-11-14
        • 2011-10-01
        • 2013-11-05
        • 2012-09-26
        相关资源
        最近更新 更多