同一机器上的两个应用程序可以绑定到相同的端口和IP地址吗?更进一步,一个应用程序可以侦听来自某个IP的请求,而另一个应用程序可以侦听来自另一个远程IP的请求吗? 我知道我可以让一个应用程序启动两个线程(或分支)具有类似的行为,但是两个没有任何共同之处的应用程序也可以这样做吗?


当前回答

答案取决于所考虑的操作系统。总的来说:

对于TCP,没有。同一时间只能有一个应用程序侦听同一端口。现在,如果您有2个网卡,您可以让一个应用程序在第一个IP上侦听,第二个应用程序在第二个IP上侦听,使用相同的端口号。

对于UDP (Multicasts),多个应用程序可以订阅同一个端口。

编辑:自Linux Kernel 3.9及更高版本以来,使用SO_REUSEPORT选项添加了对多个应用程序侦听同一端口的支持。更多信息可以在lwn.net文章中找到。

其他回答

肯定是的。据我所知,从内核版本3.9(不确定版本)开始,就引入了对SO_REUSEPORT的支持。SO_RESUEPORT允许绑定到完全相同的端口和地址,只要第一个服务器在绑定套接字之前设置了这个选项。

它适用于TCP和UDP。有关更多详细信息,请参阅链接:SO_REUSEPORT

分享一下@jnewton提到的内容。 我在我的mac上启动了一个nginx和一个嵌入式tomcat进程。我可以看到两个进程都运行在8080。

LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN
tcp46      0      0  *.8080                 *.*                    LISTEN     
tcp4       0      0  *.8080                 *.*                    LISTEN   

我用socat尝试过以下方法:

socat TCP-L:8080,fork,reuseaddr -

而且,即使我没有建立到套接字的连接,我也不能在同一个端口上侦听两次,尽管有reuseaddr选项。

我得到了这条消息(这是我之前预期的):

2016/02/23 09:56:49 socat[2667] E bind(5, {AF=2 0.0.0.0:8080}, 16): Address already in use

简短的回答:

根据这里给出的答案。您可以让两个应用程序侦听相同的IP地址和端口号,只要其中一个端口是UDP端口,而另一个是TCP端口。

解释:

端口的概念与TCP/IP堆栈的传输层相关,因此只要使用堆栈的不同传输层协议,就可以让多个进程侦听相同的< IP -address>:<port>组合。

人们有一个疑问,如果两个应用程序运行在相同的<ip-address>:<端口>组合上,那么在远程机器上运行的客户机如何区分这两个应用程序?如果你看一下IP层数据包头(https://en.wikipedia.org/wiki/IPv4#Header),你会发现第72位到第79位是用来定义协议的,这就是如何区分的。

然而,如果你想让两个应用程序在相同的TCP < IP -address>:<port>组合上,那么答案是否定的(一个有趣的练习是启动两个vm,给它们相同的IP地址,但不同的MAC地址,看看会发生什么——你会注意到有些时候VM1将获得数据包,而其他时候VM2将获得数据包——这取决于ARP缓存刷新)。

我认为,通过让两个应用程序在相同的<op-address>:<端口>上运行,可以实现某种负载平衡。为此,您可以在不同的端口上运行应用程序,并编写IP表规则来划分它们之间的流量。

请参见@user6169806的回答。

您可以让两个应用程序侦听同一个网络接口上的同一个端口。

指定的网络接口和端口只能有一个监听套接字,但该套接字可以在多个应用程序之间共享。

如果你在一个应用进程中有一个监听套接字,并且你fork了这个进程,这个套接字将被继承,所以从技术上讲,现在将有两个进程监听同一个端口。