【问题标题】:2 Processes listening on the same port - .NET not throwing exception2 侦听同一端口的进程 - .NET 不抛出异常
【发布时间】:2012-11-01 18:59:08
【问题描述】:

下图显示了 2 个进程尝试并成功地将侦听套接字(服务器)绑定到我本地计算机上的端口 10000:

这是 netstat 的输出(用于确认):

netstat -a -n | find "10000"
  TCP    0.0.0.0:10000          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:10000          0.0.0.0:0              LISTENING
  TCP    [::]:10000             [::]:0                 LISTENING

(注意:javaw.exe 进程是第一个在 10000 上打开侦听套接字的进程)。

虽然我知道多个进程确实可以在同一个端口(SO_REUSEADDR) 上侦听的情况,但在我的特定场景中有些事情困扰着我:

  1. 在我的应用程序中,我特别对 .NET 说我想要一个独占监听套接字 (SO_EXCLUSIVEADDRUSE),通过

    listener = new TcpListener(adr, ipport);
    listener.ExclusiveAddressUse = true;
    
  2. .NET 确实抛出任何类型的异常/错误/端口已在使用中的通知。事实上,它实际上相信一切都很顺利。

  3. 从此时起,我的服务器应用程序永远不会从 listener.AcceptTcpClient() 调用中唤醒。应该与服务器通信的客户端应用程序接收到一个有效的连接,但无法与“我的”服务器通信(可能是因为它建立了与不使用其“协议”的“其他”进程的连接)。

如果有人想尝试重现我的发现:第二个过程是 Eclipse (PHP) 的“Helios”版本。但具体的进程在这里并不重要:如果一个进程可以在操作系统下做奇怪的事情,那么其他进程也可以。

关于如何获得错误或完全防止这种情况(通过附加参数)的任何建议?

【问题讨论】:

  • MSDN says 该行为可能取决于您的操作系统(请参阅此处的备注)。只是猜测要检查的内容。
  • This 对独占地址的使用提供了更高级的概述,但这并没有帮助,因为它似乎不像“宣传的那样”工作(我在 Win7 上),除非我'我错过了一些重要的东西。
  • 我认为这取决于其他进程如何设置其套接字。具体来说,我无法用我现有的任何打开的套接字重现该问题。不过,我同意您发现 .NET Framework 存在问题,假设它可重复的。

标签: .net sockets networking port


【解决方案1】:

您在评论中发布的MSDN link 似乎回答了您的问题。

它与绑定到通配符 IP 端点的 java 应用程序有关(0.0.0.0 ip4;:: 用于 ip6,或IPEndpoint.ANY)。我假设上面代码 sn-p 中的 adr 变量是一个特定的 IP 地址,而不是通配符地址。

看看那篇文章中的表格。它列出了尝试使用不同的套接字选项组合再次绑定到特定或通配符端点的结果。

简而言之,Java 代码绑定在通配符 0.0.0.0 端点上,而没有 SO_EXCLUSIVEADDRUSE 套接字选项。该矩阵显示,当这种情况发生时,您可以成功绑定到一个特定地址并通过请求独占地址使用。

如果您尝试使用通配符进行绑定,表格显示调用将失败。

【讨论】:

    【解决方案2】:

    不知道为什么它没有抛出异常。虽然,文档说TcpListener 的构造函数并没有真正验证端口是否打开,因此,它只会在端口号无效时抛出ArgumentException。其他方法,如Start 将抛出一个SocketException 并将ErrorCode 设置为WSAEADDRINUSE (10048) 当端口已被另一个进程打开时(请参阅Start methodSocket Error Codes)。

    为防止这种情况,请调用Start 并捕获SocketException 或使用命名空间System.Net.NetworkInformation 来查询所有使用的端口并确定特定端口是否可用,如以下答案:In C#, how to check if a TCP port is available?

    【讨论】:

      【解决方案3】:

      我相信您实际上需要启用 TCP 端口共享 - 我现在正在使用手机,所以目前我能做的最好的事情就是删除一个链接: Net.TCP Port Sharing

      【讨论】:

      • 您链接到的文章是关于 WCF 中可用的 net.tcp:// 协议,这是一种 Microsoft 自定义 TCP 派生的通信协议。它位于 TCP 的“顶部”...
      • 啊,过失——应该更仔细地阅读这个问题;是的,我相信在这种情况下,TCP 共享对您没有帮助。
      【解决方案4】:

      http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.exclusiveaddressuse.aspx - 请注意有关 ExclusiveAddressUse 的一些操作系统差异。尝试以管理员身份运行。另一个想法,尝试进入您的计算机管理 -> 服务并停止 Net.Tcp 端口共享服务。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-22
        • 1970-01-01
        • 2016-02-17
        • 2015-03-18
        • 1970-01-01
        • 2019-05-28
        • 2017-06-04
        相关资源
        最近更新 更多