2012-12-05 64 views
7

我试图通过用netcat监听某些端口来调试OS X上的Jenkins中的端口分配问题,这导致了一些奇怪的结果。为什么OS X允许两次在同一个TCP端口上侦听?


在关于OS的终端X 10.8.2:

$ uname -rs 
Darwin 12.2.1 

$ nc -l 54321 

然后,在一个第二端子:

$ nc -l 54321

而在一个第三端子,lsof表明这两种情况下已经绑定到相同的端口:

$ lsof -i | grep 54321 
nc 70706 chris 3u IPv4 0x55618c024692f4d1  0t0 TCP *:54321 (LISTEN) 
nc 70769 chris 3u IPv4 0x55618c0232cb8661  0t0 TCP *:54321 (LISTEN) 

在Linux上:

第一终端:

$ uname -rs 
Linux 3.2.0-34-generic 

$ nc -l 54321 

第二终端:

$ nc -l 54321 
nc: Address already in use 

为什么不OS X还报告说,该地址已在使用?

+1

我不知道'lsof -i'输出语法,但是'0x55618c024692f4d1'和'0x55618c0232cb8661'是什么?如果它是IP地址,那显然是因为监听器被绑定到特定的IP地址而不是“任何”地址。 – CodeCaster

+0

他们是无意义的内存地址。它们唯一的目的是确定它们是两个不同的套接字(例如,不是fork()或dup()的结果)。 – duskwuff

+0

运行'lsof -i'为我提供了27个唯一值(“DEVICE”);我相信这是一个内存地址。最后一列显示套接字绑定到'*'。 –

回答

6

OS X上的二进制文件设置SO_REUSEPORT套接字选项,该选项允许完全重复的绑定(setsockopt on OS X)。您可以在OS X上使用dtrace进行验证。

Linux上的netcat二进制文件不会执行此操作,因此您会遇到预期的绑定错误。再次,您可以验证使用strace。我相信SO_REUSEPORT已被弃用,或者甚至在更新的Linux内核上不可用。

+0

感谢您的信息!这也解释了为什么如果另一个软件运行,'nc' *确实*抱怨端口已被使用。 –

+0

有关信息,SO_REUSEPORT套接字选项已添加到Linux 3.9:https://lwn.net/Articles/542629/ –