2侦听同一端口的进程 - .NET不会抛出异常

MrC*_*rCC 18 .net sockets port networking

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

Sysinternals在端口10000上显示2个绑定

这是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
Run Code Online (Sandbox Code Playgroud)

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

虽然我知道多个进程确实可以在同一个端口(SO_REUSEADDR)上侦听的情况,但在我的特定情况下有些事情让我感到烦恼:

  1. 在我的应用程序中,我特别向.NET说我想要一个独有的 listen socket(SO_EXCLUSIVEADDRUSE)via

    listener = new TcpListener(adr, ipport);
    listener.ExclusiveAddressUse = true;
    
    Run Code Online (Sandbox Code Playgroud)
  2. .NET并没有抛出任何类型的异常/错误/通知该端口已在使用.事实上,它实际上认为一切都很顺利.

  3. 从那时起,我的服务器应用程序永远不会从listener.AcceptTcpClient()呼叫中唤醒.应该与服务器通信的客户端应用程序接收有效连接,但无法与"我的"服务器通信(据推测,因为它建立了与"其他"进程的连接,该进程不会说"协议").

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

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

Chr*_*ens 4

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

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

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

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

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