Answers:
答案因所考虑的操作系统而异。一般而言:
对于TCP,否。一次只能有一个应用程序在同一端口上侦听。现在,如果您有2个网卡,则可以让一个应用程序使用相同的端口号监听第一个IP,第二个监听第二个IP。
对于UDP(多播),多个应用程序可以订阅同一端口。
编辑:自Linux Kernel 3.9及更高版本起,使用该SO_REUSEPORT
选项添加了对侦听同一端口的多个应用程序的支持。有关更多信息,请参见lwn.net。
是的(对于TCP),如果程序被设计为可以在同一个套接字上侦听两个程序。由第一个程序创建套接字时,请先确保SO_REUSEADDR
已在套接字上设置了该选项bind()
。但是,这可能不是您想要的。这样做是将传入TCP连接定向到其中一个程序,而不是两者都定向,因此它不会重复连接,它只允许两个程序为传入请求提供服务。例如,Web服务器将有多个进程都在端口80上侦听,并且O / S将新连接发送到准备接受新连接的进程。
SO_REUSEADDR
允许其他套接字连接bind()
到该端口,除非已经有活动的侦听套接字绑定到该端口。当您在崩溃后尝试重新启动服务器时,这使您能够解决那些“地址已在使用中”的错误消息。
SO_REUSEADDR
当然,至少在Unix上,肯定不允许两个TCP套接字同时处于侦听状态。它旨在解决TIME_WAIT state
:unixguide.net/network/socketfaq/4.5.shtml。它可能在Windows上可以运行,但不能保证无论如何该请求都会到达正确的服务器。
是。
如果它们都绑定到不同的本地IP地址,则可以将多个侦听TCP套接字(都绑定到同一端口)共存。客户端可以连接到所需的任何一个。这不包括0.0.0.0
(INADDR_ANY
)。
多个接受的套接字可以共存,所有套接字都从同一个侦听套接字接受,并且都显示与侦听套接字相同的本地端口号。
提供与(1)相同的条件,可以将全部绑定到同一端口的多个UDP套接字共存,或者SO_REUSEADDR
在绑定之前都设置了选项。
TCP端口和UDP端口占用不同的名称空间,因此将端口用于TCP并不排除将其用于UDP,反之亦然。
参考:Stevens&Wright,TCP / IP图解,第二卷。
原则上不可以。
它不是一成不变的。但这是编写所有API的方式:该应用程序打开一个端口,获取该端口的句柄,然后当客户端连接(或UDP情况下的数据包)到达时,操作系统(通过该句柄)通知该端口。
如果操作系统允许两个应用程序打开相同的端口,它将如何知道要通知哪个应用程序?
但是...有一些解决方法:
iptables -m statistic --mode random --probability 0.5
有趣。
listen()
打开的套接字时发生的。问题很可能是关于在防火墙中打开它。这里的错误太多,而且7年内都未纠正。答案还省略了绑定到具有相同端口号的不同本地地址的情况。实际上这是完全不正确的。
是的。据我记得,从3.9版内核(不确定该版本)开始,SO_REUSEPORT
就引入了对它的支持。SO_RESUEPORT
允许绑定到完全相同的端口和地址,只要第一台服务器在绑定其套接字之前设置此选项。
它适用于TCP和UDP。请参阅链接以获取更多详细信息:SO_REUSEPORT
注意:根据我的观点,接受的答案不再成立。
否。一次只能将一个应用程序绑定到端口,如果强制执行绑定,则行为是不确定的。
使用多播套接字-听起来像没有想要的东西-只要在每个套接字的选项中设置了SO_REUSEADDR,就可以将多个应用程序绑定到一个端口。
您可以通过编写一个“主”进程来完成此任务,该进程接受并处理所有连接,然后将它们交给需要在同一端口上侦听的两个应用程序。这是Web服务器之类的方法,因为许多进程需要监听80。
除此之外,我们还将介绍一些细节-您标记了TCP和UDP,是吗?还有,什么平台?
您可以让一个应用程序在一个端口上侦听一个网络接口。因此,您可以:
httpd
在远程访问界面上侦听,例如 192.168.1.1:80
127.0.0.1:80
示例用例可以httpd
用作负载平衡器或代理。
另一种方法是使用一个程序在一个端口中侦听,该程序分析其内部重定向到“真实”服务正在侦听的另一个端口的流量(ssh,https等)。
例如,对于Linux,sslh:https : //github.com/yrutschle/sslh
创建TCP连接时,您要求连接到特定的TCP地址,该地址是IP地址(v4或v6,取决于所使用的协议)和端口的组合。
当服务器侦听连接时,它可以通知内核它想侦听特定的IP地址和端口,即一个TCP地址,或者侦听主机IP地址中每个主机的同一端口(通常用IP地址指定)0.0.0.0
),其上有很多不同的“TCP地址”的有效监听(例如,192.168.1.10:8000
,127.0.0.1:8000
等等)
不,您不能让两个应用程序侦听相同的“ TCP地址”,因为当消息进入时,内核如何知道向哪个应用程序发送消息?
但是,在大多数操作系统中,您可以在一个接口上设置多个IP地址(例如,如果192.168.1.10
在接口上,则还可以设置192.168.1.11
,如果网络上没有其他人正在使用它),在这种情况下,您可以可能有单独的应用程序在8000
这两个IP地址的每个端口上侦听端口。
只是分享@jnewton提到的内容。我在Mac上启动了nginx和嵌入式tomcat进程。我可以在8080看到两个进程runninng。
LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN
tcp46 0 0 *.8080 *.* LISTEN
tcp4 0 0 *.8080 *.* LISTEN
简短答案:
按照这里给出的答案。您可以让两个应用程序侦听相同的IP地址和端口号,因此一个端口只要是UDP端口,而另一个是TCP端口即可。
说明:
端口的概念与TCP / IP堆栈的传输层相关,因此,只要您使用堆栈的不同传输层协议,就可以使多个进程侦听相同的<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表规则以分流它们之间的流量。
另请参阅@ user6169806的答案。