答案取决于所考虑的操作系统。总的来说:
对于TCP,没有。同一时间只能有一个应用程序侦听同一端口。现在,如果您有2个网卡,您可以让一个应用程序在第一个IP上侦听,第二个应用程序在第二个IP上侦听,使用相同的端口号。
对于UDP (Multicasts),多个应用程序可以订阅同一个端口。
编辑:自Linux Kernel 3.9及更高版本以来,使用SO_REUSEPORT选项添加了对多个应用程序侦听同一端口的支持。更多信息可访问这是lwn.net的文章。
SO_REUSEPORT
不。一次只能有一个应用程序绑定到一个端口,强制绑定时的行为是不确定的。
使用多播套接字(听起来与您想要的相距甚远),只要在每个套接字的选项中设置SO_REUSEADDR,就可以有多个应用程序绑定到一个端口。
您可以通过编写一个“主”进程来实现这一点,该进程接受并处理所有连接,然后将它们交给需要侦听同一端口的两个应用程序。这是Web服务器等采用的方法,因为许多进程需要侦听80。
除此之外,我们将讨论细节——您同时标记了TCP和UDP,是哪个?还有,什么平台?
原则上,没有。
这不是刻在石头上的;但这是所有api的编写方式:应用程序打开一个端口,获得它的句柄,当客户端连接(或UDP情况下的数据包)到达时,操作系统(通过该句柄)通知它。
如果操作系统允许两个应用程序打开同一个端口,它怎么知道该通知哪一个呢?
但是…有一些方法可以解决这个问题:
如果至少有一个远程ip是已知的,静态的,专用于只与你的一个应用程序对话,你可以使用iptables规则(表nat,链PREROUTING)来重定向从这个地址到“共享”本地端口的传入流量到任何其他端口,其中适当的应用程序实际监听。
是的(对于TCP),你可以让两个程序侦听同一个套接字,如果这些程序是这样设计的。当第一个程序创建套接字时,确保在bind()之前在套接字上设置了SO_REUSEADDR选项。然而,这可能不是你想要的。这样做的目的是将传入的TCP连接定向到程序的一个,而不是同时指向两个程序,因此它不会复制连接,它只允许两个程序为传入的请求提供服务。例如,web服务器将有多个进程在端口80上监听,然后O/S将一个新连接发送给准备好接受新连接的进程。
bind()
SO_REUSEADDR
允许其他套接字bind()到该端口,除非已经有一个活动监听套接字绑定到该端口。这使您能够在崩溃后尝试重新启动服务器时绕过“地址已在使用”错误消息。
是也不是。只有一个应用程序可以在一个端口上进行主动侦听。但是该应用程序可以将其连接遗留给另一个进程。因此,您可以让多个进程在同一个端口上工作。
如果你指的应用程序是多个进程,那么是,但通常不是。 例如Apache服务器在同一个端口上运行多个进程(通常是80)。它通过指定一个进程实际绑定到端口,然后使用该进程向接受连接的各个进程进行切换来实现。< / p >
是的。
如果多个侦听TCP套接字都绑定到不同的本地IP地址,它们就可以共存,这些套接字都绑定到同一个端口。客户端可以连接到他们需要的任何一个。这不包括0.0.0.0 (INADDR_ANY)。
0.0.0.0
INADDR_ANY
多个accept 套接字可以共存,都是从同一个侦听套接字接受的,都显示与侦听套接字相同的本地端口号。
绑定到同一端口的多个UDP套接字都可以共存,前提是与(1)相同的条件,或者它们在绑定之前都设置了SO_REUSEADDR选项。
TCP端口和UDP端口占用不同的命名空间,因此TCP端口的使用并不排除其UDP端口的使用,反之亦然
参考资料:Stevens &赖特,TCP / IP了,卷II。
您可以让两个应用程序侦听同一个网络接口上的同一个端口。
指定的网络接口和端口只能有一个监听套接字,但该套接字可以在多个应用程序之间共享。
如果你在应用程序进程中有一个监听套接字,并且你fork了这个进程,这个套接字将被继承,所以从技术上讲,现在将有两个进程监听同一个端口。
fork
另一种方法是使用一个程序在一个端口上监听,该程序分析流量类型(ssh、https等),它将在内部重定向到另一个“真正的”服务正在监听的端口。
例如,对于Linux, sslh: https://github.com/yrutschle/sslh
您可以让一个应用程序侦听一个网络接口的一个端口。因此你可以有:
httpd
192.168.1.1:80
127.0.0.1:80
示例用例可以是使用httpd作为负载均衡器或代理。
简短的回答:
根据给出的答案在这里。您可以让两个应用程序侦听相同的IP地址和端口号,只要其中一个端口是UDP端口,而另一个是TCP端口。
解释:
端口的概念与TCP/IP堆栈的传输层相关,因此只要使用堆栈的不同传输层协议,就可以让多个进程侦听相同的<ip-address>:<port>组合。
<ip-address>:<port>
人们有一个疑问是,如果两个应用程序运行在相同的<ip-address>:<port>组合上,在远程机器上运行的客户端如何区分这两个应用程序?如果你看一下IP层包头(https://en.wikipedia.org/wiki/IPv4#Header),你会发现第72位到第79位是用来定义协议的,这就是如何区分的。
然而,如果你想让两个应用程序在相同的TCP <ip-address>:<port>组合上,那么答案是不(一个有趣的练习是启动两个vm,给它们相同的IP地址,但不同的MAC地址,看看会发生什么——你会注意到有些时候VM1会得到数据包,而其他时候VM2会得到数据包——这取决于ARP缓存刷新)。
我觉得通过让两个应用程序运行在同一个<op-address>:<port>上,你想要达到某种负载平衡。为此,您可以在不同的端口上运行应用程序,并编写IP表规则来划分它们之间的流量。
<op-address>:<port>
请参见@user6169806的回答。
我已经用socat尝试了以下方法:
socat
socat TCP-L:8080,fork,reuseaddr -
即使我没有建立到套接字的连接,我也不能在同一个端口上侦听两次,尽管有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
来自这篇文章: https://lwn.net/Articles/542629/ < / p >
新的套接字选项允许同一主机上的多个套接字绑定到同一个端口
在创建TCP连接时,您要求连接到特定的TCP地址,该地址是IP地址(v4或v6,取决于您使用的协议)和端口的组合。
当服务器监听连接时,它可以通知内核它想监听一个特定的IP地址和端口,即一个TCP地址,或者在每个主机的IP地址(通常用IP地址0.0.0.0指定)上的相同端口,这实际上是在监听许多不同的“TCP地址”(例如,192.168.1.10:8000, 127.0.0.1:8000等)。
192.168.1.10:8000
127.0.0.1:8000
不,您不能让两个应用程序侦听同一个“TCP地址”,因为当消息传入时,内核如何知道该将消息传递给哪个应用程序?
然而,在大多数操作系统中,你可以在一个接口上设置多个IP地址(例如,如果你在一个接口上有192.168.1.10,你也可以设置192.168.1.11,如果网络上没有其他人在使用它),在这种情况下,你可以让不同的应用程序在这两个IP地址的每个端口上监听8000。
192.168.1.10
192.168.1.11
8000
肯定是的。据我所知,从内核版本3.9(不确定版本)起,就引入了对SO_REUSEPORT的支持。SO_RESUEPORT允许绑定到完全相同的端口和地址,只要第一个服务器在绑定套接字之前设置了这个选项。
SO_RESUEPORT
它适用于TCP和UDP。更多细节请参考链接:SO_REUSEPORT
LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN tcp46 0 0 *.8080 *.* LISTEN tcp4 0 0 *.8080 *.* LISTEN