Sockets 两个应用程序能否侦听同一端口?

Sockets 两个应用程序能否侦听同一端口?,sockets,tcp,udp,port,communication,Sockets,Tcp,Udp,Port,Communication,同一台机器上的两个应用程序能否绑定到同一端口和IP地址?更进一步说,一个应用程序可以监听来自某个IP的请求,而另一个应用程序可以监听来自另一个远程IP的请求吗? 我知道我可以有一个应用程序启动两个线程(或分叉)以具有相似的行为,但是两个没有共同点的应用程序可以做相同的事情吗?答案取决于所考虑的操作系统。但总体而言: 对于TCP,不能。一次只能有一个应用程序在同一端口上侦听。现在,如果您有两个网卡,您可以让一个应用程序使用相同的端口号在第一个IP上侦听,第二个应用程序在第二个IP上侦听 对于UDP

同一台机器上的两个应用程序能否绑定到同一端口和IP地址?更进一步说,一个应用程序可以监听来自某个IP的请求,而另一个应用程序可以监听来自另一个远程IP的请求吗?
我知道我可以有一个应用程序启动两个线程(或分叉)以具有相似的行为,但是两个没有共同点的应用程序可以做相同的事情吗?

答案取决于所考虑的操作系统。但总体而言:

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

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


编辑:自Linux内核3.9及更高版本以来,使用
SO\u REUSEPORT
选项添加了对侦听同一端口的多个应用程序的支持。有关详细信息,请参见编号。一次只能有一个应用程序绑定到一个端口,并且强制绑定时的行为是不确定的

对于多播套接字(听起来与您想要的相差甚远),只要在每个套接字的选项中设置了_REUSEADDR,就可以将多个应用程序绑定到一个端口

您可以通过编写一个“主”进程来实现这一点,该进程接受并处理所有连接,然后将它们交给需要在同一端口上侦听的两个应用程序。这是Web服务器等采用的方法,因为许多进程需要侦听80

除此之外,我们还要讨论一些细节——您同时标记了TCP和UDP,是哪一种?还有,什么平台?

原则上,没有

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

如果操作系统允许两个应用打开同一个端口,它怎么知道应该通知哪一个

但是。。。有很多方法可以解决这个问题:

  • 作为Jed,您可以编写一个“主”进程,它将是唯一一个真正监听端口并通知其他人的进程,使用它想要分离客户端请求的任何逻辑。
    • 在Linux和BSD(至少)上,您可以设置“重新映射”规则,根据任何与网络相关的标准(可能是源网络,或一些简单的负载平衡形式),将数据包从“可见”端口重定向到不同的端口(应用正在侦听的端口)

  • 如果至少有一个远程IP是已知的、静态的且专用于只与您的一个应用程序通话,您可以使用iptables规则(表nat,链预路由)将输入流量从该地址重定向到“共享”本地端口,再重定向到相应应用程序实际侦听的任何其他端口。

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

    SO_REUSEADDR
    

    允许其他套接字
    bind()
    到此端口,除非已将活动侦听套接字绑定到此端口。这使您能够在崩溃后尝试重新启动服务器时绕过那些“地址已在使用”错误消息。

    是和否。只有一个应用程序可以在端口上主动侦听。但该应用程序可以将其连接遗留到另一个进程。因此,您可以让多个进程在同一端口上工作。

    如果应用程序指的是多个进程,那么是,但通常不是。 例如,Apache服务器在同一个端口上运行多个进程(通常为80个)。这是通过指定一个进程实际绑定到端口,然后使用该进程切换到接受连接的各个进程来完成的

    是的

  • 如果多个侦听TCP套接字都绑定到不同的本地IP地址,则它们都绑定到同一端口,可以共存。客户端可以连接到他们需要的任何一个。这不包括
    0.0.0.0
    INADDR\u ANY

  • 多个接受的套接字可以共存,它们都来自同一个侦听套接字,都显示与侦听套接字相同的本地端口号

  • 多个绑定到同一端口的UDP套接字可以共存,条件与(1)相同,或者它们在绑定之前都设置了
    SO\u REUSEADDR
    选项

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


  • 参考:Stevens&Wright,《TCP/IP图解》,第二卷。

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

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


    如果您在应用程序进程中有一个侦听套接字,并且您
    fork
    该进程,那么该套接字将被继承,因此从技术上讲,现在将有两个进程侦听同一端口。

    另一种方法是在一个端口中使用一个程序侦听,以分析流量的类型(ssh、https等)它在内部重定向到另一个端口,“真正的”服务正在侦听


    例如,对于Linux,sslh:

    您可以让一个应用程序在一个端口上监听一个网络接口。因此,你可以:<
    socat TCP-L:8080,fork,reuseaddr -
    
    2016/02/23 09:56:49 socat[2667] E bind(5, {AF=2 0.0.0.0:8080}, 16): Address already in use
    
    LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN
    tcp46      0      0  *.8080                 *.*                    LISTEN     
    tcp4       0      0  *.8080                 *.*                    LISTEN