linux多播 多个接收方,在同一端口上接收多个多播源 – C,Linux

这篇博客讨论了一个Linux应用程序如何从同一端口上的多个组播源接收数据的问题。通过使用IP_ADD_MEMBERSHIP套接字选项和SO_REUSEPORT选项,可以实现多个套接字绑定到同一端口,每个套接字对应一个组播组。通过这种方法,来自不同组的数据可以被正确地路由到不同的套接字,以便进行统计和区分。

我有一个应用程序从同一端口上的多个组播源接收数据.我能够收到数据.但是,我试图考虑每个组的统计数据(即收到的消息,接收的字节数),并且所有数据都混淆了.有谁知道如何解决这个问题?如果我试着查看发件人的地址,那么它不是多播地址,而是发送机器的IP.

我使用以下套接字选项:

struct ip_mreq mreq;

mreq.imr_multiaddr.s_addr = inet_addr("224.1.2.3");

mreq.imr_interface.s_addr = INADDR_ANY;

setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

并且:

setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse));

解决方法:

[编辑澄清bind()实际上可能包含多播地址.]

因此,应用程序正在连接多个多播组,并将发送到其中任何一个的消息接收到同一端口. SO_REUSEPORT允许您将多个套接字绑定到同一端口.除端口外,bind()还需要一个IP地址. INADDR_ANY是一个包罗万象的地址,但也可以使用IP地址,包括多播地址.在这种情况下,只有发送到该IP的数据包才会被传送到套接字.即您可以创建多个套接字,每个多播组一个. bind()每个套接字到(group_addr,port),并加入group_addr.然后,发往不同组的数据将显示在不同的套接字上,您将能够以这种方式区分它.

我测试了以下适用于FreeBSD:

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc, const

在某些场景下,需要多个接收端共享同一端口进行数据监听或处理。实现这一需求的方式取决于具体的协议(如 TCP 或 UDP)以及操作系统的支持能力。 ### 使用 TCP 共享端口 对于 TCP 协议,在 Linux 系统中可以通过 `SO_REUSEPORT` 套字选项允许多个进程绑定到同一端口。此功能从 Linux 3.9 内核版本开始引入,并且适用于多线程或多进程服务器应用。 示例代码如下: ```c #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> int main() { int sockfd1 = socket(AF_INET, SOCK_STREAM, 0); int sockfd2 = socket(AF_INET, SOCK_STREAM, 0); int reuse = 1; setsockopt(sockfd1, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)); setsockopt(sockfd2, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = INADDR_ANY; bind(sockfd1, (struct sockaddr*)&addr, sizeof(addr)); bind(sockfd2, (struct sockaddr*)&addr, sizeof(addr)); listen(sockfd1, 5); listen(sockfd2, 5); printf("Listening on port 8080 with two sockets.\n"); while (1) { // 接收逻辑 } return 0; } ``` 该方法可以用于负载均衡或者高并发的服务设计中,使得多个服务实例能够并行处理请求[^3]。 ### 使用 UDP 共享端口 UDP 的共享端口配置相对简单,因为 UDP 是无连的协议。多个 UDP 套字可以绑定到相同端口而无需特别设置 `SO_REUSEPORT`。每个套字独立接收发送到该端口的数据包。 示例代码如下: ```c #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <stdio.h> int main() { int sockfd1 = socket(AF_INET, SOCK_DGRAM, 0); int sockfd2 = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = INADDR_ANY; bind(sockfd1, (struct sockaddr*)&addr, sizeof(addr)); bind(sockfd2, (struct sockaddr*)&addr, sizeof(addr)); printf("Listening on UDP port 8080 with two sockets.\n"); while (1) { // 接收数据报逻辑 } return 0; } ``` 通过这种方式,可以在同一台主机上运行多个服务监听相同的 UDP 端口[^2]。 ### Nginx 配置共享端口 如果使用 Nginx 作为反向代理或负载均衡器,则可以通过配置多个 `server` 块来监听同一端口。例如: ```nginx server { listen 8080; server_name example.com; location / { proxy_pass http://backend1; } } server { listen 8080; server_name another.example.com; location / { proxy_pass http://backend2; } } ``` Nginx 将根据请求中的 Host 头来决定将流量路由到哪个后端服务[^5]。 ### 总结 共享端口的实现方式因协议和环境而异。TCP 需要启用 `SO_REUSEPORT`,而 UDP 可以直绑定相同端口;Nginx 则提供了基于名称的虚拟主机功能来实现端口共享。这些方法可以根据具体应用场景灵活选择和配置。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值