当前位置:  开发笔记 > 程序员 > 正文

两个应用程序可以侦听同一个端口吗?

如何解决《两个应用程序可以侦听同一个端口吗?》经验,为你挑选了6个好方法。

同一台机器上的两个应用程序可以绑定到同一个端口和IP地址吗?更进一步,一个应用程序可以收听来自某个IP和另一个远程IP的请求吗?我知道我可以有一个应用程序从两个线程(或叉子)开始有类似的行为,但两个没有任何共同点的应用程序可以做同样的事情吗?



1> Chris Dail..:

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

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


每个IP地址每个端口一个侦听器.添加另一个网络接口是获取第二个IP地址的一种方法.您的平台可能支持虚拟接口,这是通过一个物理网卡获取两个IP地址的另一种方法.
"一个应用程序侦听单个端口"这就是端口存在的原因 - 允许多个应用程序共享网络而不会发生冲突.
**对于UDP(多播),多个应用程序可以订阅同一个端口.**如果一个数据包已从客户端到达,哪个应用程序接收它?
虽然到目前为止我的意见相同,但事实证明我能够将两个不同的进程绑定到同一个ip和TCP端口!如果在绑定到Java之前在Java中设置ServerSocket.setReuseAddress(true),则可以执行此操作.真意外的行为.
(1)你的答案的实际含义是'For TCP,*yes,*provided ...'(2)组播不是UDP端口共享的前提条件,但是SO_REUSEADDR是.
@Eugen还注意到Java bug [7179799](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7179799),这可能发生在具有多个Java版本的Windows上.
@Chris,此答案具有误导性,应进行编辑/删除。

2> 小智..:

是(对于TCP),如果程序设计为可以,则可以在同一个套接字上侦听两个程序.当套接字由第一个程序创建时,请确保SO_REUSEADDR在您之前在套接字上设置该选项bind().但是,这可能不是你想要的.这样做的是传入的TCP连接将被定向到其中一个程序,而不是两个,因此它不会复制连接,它只允许两个程序为传入的请求提供服务.例如,Web服务器将有多个进程都在端口80上进行侦听,并且O/S会向准备接受新连接的进程发送新连接.

SO_REUSEADDR

允许其他套接字bind()到此端口,除非已有绑定到端口的活动侦听套接字.这使您可以在崩溃后尝试重新启动服务器时绕过那些"已在使用中的地址"错误消息.


这个答案是不正确的,除非所有的插座被绑定到不同的IP地址,其中没有一个是INADDR_ANY,或除非你是在Windows上,这里的结果是不确定的.
当然,至少在Unix上,“ SO_REUSEADDR”不允许您同时使两个TCP套接字处于侦听状态。它的意思是避开“ TIME_WAIT状态”:http://www.unixguide.net/network/socketfaq/4.5.shtml。它可能在Windows上可以运行,但不能保证无论如何该请求都会到达正确的服务器。

3> Javier..:

原则上,没有.

它不是一成不变的; 但它是所有API编写的方式:应用程序打开一个端口,获取它的句柄,当客户端连接(或UDP情况下的数据包)到达时,操作系统通知它(通过该句柄).

如果操作系统允许两个应用程序打开同一个端口,它将如何知道要通知哪个?

但是......有很多方法可以解决它:

    正如Jed所指出的那样,你可以编写一个"主"进程,它将是唯一真正侦听端口并通知其他人的进程,使用它想要分离客户端请求的任何逻辑.

    在Linux和BSD(至少)上,您可以设置"重新映射"规则,根据任何网络相关标准(可能是原始网络,或某些网络),将数据包从"可见"端口重定向到不同的端口(应用正在侦听的位置)简单的负载均衡形式).


`iptables -m statistic --mode random --probability 0.5`很有趣.
这个答案不能被认为是正确的.它完全忽略了SO_REUSEADDR和SO_REUSEPORT的存在.
@Samuel:打开一个端口(在服务器模式下)意味着获取文件描述符,当系统获得一个SYN数据包到该端口号时,用SYN + ACK响应并在相关的文件描述符上生成一个事件.应用程序使用accept()调用响应该事件,该调用创建与特定流关联的新文件描述符,使原始服务器描述符可以自由获取来自客户端的新连接

4> user207421..:

是.

    多个侦听TCP套接字都可以共存,只要它们都绑定到不同的本地IP地址,它们都可以共存.客户可以连接到他们需要的任何一个.这不包括0.0.0.0(INADDR_ANY).

    多个接受的套接字可以共存,所有套接字都可以从同一个侦听套接字接收,所有套接字都显示与侦听套接字相同的本地端口号.

    所有绑定到同一端口的多个UDP套接字都可以共存,提供与(1)相同的条件,或者它们都SO_REUSEADDR在绑定之前设置了选项.

    TCP端口和UDP端口占用不同的命名空间,因此使用TCP端口并不排除它用于UDP,反之亦然.

参考:Stevens&Wright,TCP/IP Illustrated,第二卷.



5> piyush..:

是肯定的.据我记得从内核版本3.9(不确定版本)开始支持SO_REUSEPORT.SO_RESUEPORT允许绑定到完全相同的端口和地址,只要第一个服务器在绑定其套接字之前设置此选项.

它适用于TCPUDP.有关更多详细信息,请参阅链接:SO_REUSEPORT

注意:根据我的观点,接受的答案不再适用.


@Staszek Wireshark不听端口.它在数据包级别运行.
完全正确.如果不是这样,Wireshark如何运作?

6> Jed Smith..:

不可以.一次只能有一个应用程序绑定到端口,并且强制绑定时的行为是不确定的.

使用多播套接字 - 听起来不像您想要的那样 - 只要在每个套接字的选项中设置了SO_REUSEADDR,多个应用程序就可以绑定到端口.

您可以通过编写一个"主"进程来完成此操作,该进程接受并处理所有连接,然后将它们交给需要在同一端口上侦听的两个应用程序.这是Web服务器等采取的方法,因为许多进程需要监听80.

除此之外,我们进入细节 - 你标记了TCP和UDP,它是什么?还有什么平台?


没有多播套接字这样的东西.有UDP套接字.多播不是SO_REUSEADDR的先决条件.
推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有