在man pages
和程序员单证套接字选项SO_REUSEADDR
,并SO_REUSEPORT
针对不同的操作系统,不同的,往往非常混乱.有些操作系统甚至没有选项SO_REUSEPORT
.WEB中充满了关于此主题的矛盾信息,并且通常您可以找到仅对特定操作系统的一个套接字实现的信息,这些信息甚至可能在文本中没有明确提及.
那究竟有什么SO_REUSEADDR
不同SO_REUSEPORT
呢?
系统是否没有SO_REUSEPORT
更多限制?
如果我在不同的操作系统上使用任何一个,那么预期的行为究竟是什么?
下图显示了在本地计算机上尝试并成功将侦听套接字(服务器)绑定到端口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
Run Code Online (Sandbox Code Playgroud)
(注意:javaw.exe进程是第一个在10000上打开listen套接字的进程).
虽然我知道多个进程确实可以在同一个端口(SO_REUSEADDR
)上侦听的情况,但在我的特定情况下有些事情让我感到烦恼:
在我的应用程序中,我特别向.NET说我想要一个独有的 listen socket(SO_EXCLUSIVEADDRUSE
)via
listener = new TcpListener(adr, ipport);
listener.ExclusiveAddressUse = true;
Run Code Online (Sandbox Code Playgroud).NET并没有抛出任何类型的异常/错误/通知该端口已在使用.事实上,它实际上认为一切都很顺利.
从那时起,我的服务器应用程序永远不会从listener.AcceptTcpClient()
呼叫中唤醒.应该与服务器通信的客户端应用程序接收有效连接,但无法与"我的"服务器通信(据推测,因为它建立了与"其他"进程的连接,该进程不会说"协议").
如果有人想尝试重现我的发现:第二个过程是Eclipse(PHP)的"Helios"版本.但具体过程在这里并不重要:如果一个过程可以在操作系统下做奇怪的事情,那么其他过程也是如此.
关于我如何得到错误或完全阻止这种情况(通过附加参数)的任何建议?