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

同一台计算机上的两个应用程序可以绑定到相同的端口和IP地址吗? 更进一步,一个应用程序可以监听来自某个IP的请求,另一个可以监听另一个远程IP的请求吗? 我知道我可以有一个应用程序开始两个线程(或叉)具有类似的行为,但可以有两个没有共同点的应用程序相同的?

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

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

是的(对于TCP),如果程序设计为这样的话,你可以让两个程序在同一个套接字上侦听。 当套接字由第一个程序创建时,请确保在bind()之前在套接字上设置了SO_REUSEADDR选项。 但是,这可能不是你想要的。 这是一个传入的TCP连接将被定向到一个程序,而不是两个,所以它不会重复连接,它只是允许两个程序来处理传入的请求。 例如,Web服务器将有多个进程在端口80上侦听,并且O / S发送一个新的连接到准备好接受新连接的进程。

 SO_REUSEADDR 

允许其他套接字bind()到这个端口,除非已经有一个活动的监听套接字绑定到这个端口。 当您尝试在崩溃后重新启动服务器时,可以避开“地址已被使用”错误消息。

原则上没有。

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

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

但是…有办法解决这个问题:

  1. 正如Jed 指出的那样 ,您可以编写一个“主”进程,它将是唯一一个真正监听端口并通知其他人的进程,使用任何逻辑来分隔客户端请求。
    • 在Linux和BSD(至少)你可以设置'重新映射'的规则,重定向从'可见'端口的数据包到不同的(应用程序正在侦听),根据任何网络相关的标准(也许网络的起源,或一些简单的负载均衡形式)。

是。

  1. 所有绑定到同一端口的多个监听TCP套接字可以共存,只要它们全部绑定到不同的本地IP地址。 客户可以连接到他们需要的任何一个。 这不包括0.0.0.0INADDR_ANY )。

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

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

  4. TCP端口和UDP端口占用不同的名称空间,所以TCP端口的使用并不排除它用于UDP, 反之亦然。

参考文献:Stevens&Wright, TCP / IP Illustrated,第二卷。

不可以。只有一个应用程序可以一次绑定到一个端口,而绑定被强制的行为是不确定的。

使用组播套接字 – 这听起来就像你想要的任何地方 – 只要在每个套接字的选项中设置了SO_REUSEADDR,多个应用程序就可以绑定到一个端口。

你可以通过编写一个“主”进程来完成这个任务,这个进程接受和处理所有的连接,然后把它们交给你需要监听同一个端口的两个应用程序。 这是Web服务器所采取的方法,因为许多进程需要聆听80。

除此之外,我们正在进入细节 – 你标记了TCP和UDP,这是什么? 另外,什么平台?

是肯定的 。 据我记忆从内核版本3.9(不知道在版本上)向前支持SO_REUSEPORT被引入。 SO_RESUEPORT允许绑定到完全相同的端口和地址,只要第一个服务器在绑定其套接字之前设置此选项。

它适用于TCPUDP 。 请参阅链接了解更多详情: SO_REUSEPORT

:接受的答案不再按照我的意见成立。

您可以让一个应用程序在一个端口上监听一个网络接口。 所以你可以有:

  1. httpd监听远程访问的接口,例如192.168.1.1:80
  2. 另一个在127.0.0.1:80监听的守护进程

示例用例可能是使用httpd作为负载平衡器或代理。

另一种方法是使用监听一个端口的程序来分析内部重定向到另一个“真实”服务端口的流量类型(ssh,https等)。

例如,对于Linux,sslh: https : //github.com/yrutschle/sslh

如果至少有一个远程IP是已知的,静态和专用于只与您的应用程序交谈,您可以使用iptables规则(表nat,链式PREROUTING)将来自该地址的流量重定向到“共享”本地端口任何其他适当的应用程序实际监听的端口。

是和不是。 只有一个应用程序可以主动侦听端口。 但是,这个应用程序可以将它与另一个进程联系起来。 所以你可以有多个进程在同一个端口上工作。

是。

从这篇文章:
https://lwn.net/Articles/542629/

新的套接字选项允许同一主机上的多个套接字绑定到相同的端口

创建TCP连接时,要求连接到特定的TCP地址,该地址是IP地址(v4或v6,取决于您使用的协议)和端口的组合。

当一个服务器监听连接时,它可以通知内核它希望监听特定的IP地址和端口,即一个IP地址或所有主机IP地址,每个IP地址都在一个特定的端口上,这是有效的监听很多不同的“TCP地址”(例如,192.168.1.10:8000,127.0.0.1:8000等)

不,您不能让两个应用程序在相同的“TCP地址”上进行侦听,因为当有消息进入时,内核如何知道给哪个应用程序发送消息?

但是,在大多数操作系统中,您可以在单个接口上设置多个IP地址(例如,如果接口上有192.168.1.10,则也可以设置192.168.1.11,如果网络上没有其他人正在使用它) ,在这种情况下,您可以在这两个IP地址的每一个上分别监听端口8000上的应用程序。

如果通过应用程序,你的意思是多个进程然后是的,但通常没有 例如,Apache服务器在同一个端口(通常为80)上运行多个进程。通过指定一个进程实际绑定到端口,然后使用该进程切换到正在接受连接的各个进程。

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

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

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

我已经尝试了以下与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>:<port>组合上运行,那么运行在远程机器上的客户机将如何区分这两个应用程序? 如果您查看IP层数据包标头( https://en.wikipedia.org/wiki/IPv4#Header ),您会看到第72至79位用于定义协议,这是如何区分的。

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

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

另请参阅@ user6169806的答案。