Is it possible to receive data from more than one multicast group on a single socket?
是否可以在单个套接字上接收来自多个组播组的数据?
For example:
void AddGroup(int sock,
const char* mc_addr_str,
int mc_port,
const char* interface) {
struct sockaddr_in mc_addr;
memset(&mc_addr, 0, sizeof(mc_addr));
mc_addr.sin_family = AF_INET;
mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
mc_addr.sin_port = htons(mc_port);
if ((bind(sock, (struct sockaddr *) &mc_addr,
sizeof(mc_addr))) < 0) {
perror("bind() failed");
exit(1);
}
// construct an IGMP join request structure
struct ip_mreq mc_req;
mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str);
mc_req.imr_interface.s_addr = inet_addr(interface);
if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(void*) &mc_req, sizeof(mc_req))) < 0) {
perror("setsockopt() failed");
exit(1);
}
}
This code works when I add one multicast group. But when I try to add another, the "bind" fails. I don't quite understand why the bind needs to be there in the first place? (but the code doesn't work without it).
添加一个多播组时,此代码有效。但是当我尝试添加另一个时,“绑定”失败了。我不太明白为什么绑定首先需要在那里? (但没有它,代码不起作用)。
Ideally I would like to call AddGroup multiple times on the same socket. Is this possible? Or do I need one socket per group and then just use polling?
理想情况下,我想在同一个套接字上多次调用AddGroup。这可能吗?或者我是否每组需要一个套接字然后才使用轮询?
6 个解决方案
#1
6
You can join as many multicast groups as you like, using the appropriate setsockopt()
call with the IP_ADD_MEMBERSHIP option, rather than bind().
您可以使用适当的setsockopt()调用和IP_ADD_MEMBERSHIP选项(而不是bind())来加入任意数量的组播组。
#2
3
You only bind a socket once. Skip the bind the second time and see what happens.
您只绑定一次套接字。第二次跳过绑定,看看会发生什么。
#3
2
bind
to the passive address, i.e. 0.0.0.0 for IPv4 and use ASM or SSM to pull in additional groups, e.g. IP_ADD_MEMBERSHIP
as listed.
绑定到被动地址,即对于IPv4为0.0.0.0,并使用ASM或SSM来引入其他组,例如列出的IP_ADD_MEMBERSHIP。
You can only bind
once.
你只能绑定一次。
#4
2
You can join as many multicast groups you want to on a single socket. See setsockopt(), IP_PKTINFO for a way to recognize which multicast group you are reading data from.
您可以在单个套接字上加入所需数量的多播组。有关识别要从中读取数据的多播组的方法,请参阅setsockopt(),IP_PKTINFO。
#5
0
Yes, it's possible: look on the example in the link (http://www.tenouk.com/Module41c.html) To shorten this up in a few steps:
是的,这是可能的:查看链接中的示例(http://www.tenouk.com/Module41c.html)通过以下几个步骤简化此操作:
- You setsockopt with SO_REUSEADDR
- You bind on INADDR_ANY
- You setsockopt with IP_ADD_MEMBERSHIP on every group you want to receive datagram from.
- It seems to me that using IP_PKTINFO gives an option to distinguish received packets, but sender must take care about preparing them(Setting the source IP for a UDP socket)
你使用SO_REUSEADDR setockopt
您绑定INADDR_ANY
在要从其接收数据报的每个组上使用IP_ADD_MEMBERSHIP setockopt。
在我看来,使用IP_PKTINFO提供了区分收到的数据包的选项,但发送者必须注意准备它们(设置UDP套接字的源IP)
#6
-3
I do not believe it possible to join more than one multicast group on a given socket. The socket is defined by the pairing of the source ip/port and destination ip/port. The operating system would not know what to do with data that comes down from the second ip/port because it would not have a socket to send it to.
我不相信可以在给定套接字上加入多个多播组。套接字由源IP /端口和目标IP /端口的配对定义。操作系统不知道如何处理来自第二个ip / port的数据,因为它没有套接字来发送它。
The bind is necessary to register the connection with the operating system. It's basically like registering a file handle.
绑定是注册与操作系统的连接所必需的。它基本上就像注册文件句柄一样。
The best way to do this would be to create a socket for each multicast group and then call select(). select() will inform you if any socket has data ready for reading.
执行此操作的最佳方法是为每个多播组创建一个套接字,然后调用select()。如果任何套接字已准备好读取数据,select()将通知您。
Check your man pages for more info on socket(), bind(), and select().
有关socket(),bind()和select()的更多信息,请查看手册页。
#1
6
You can join as many multicast groups as you like, using the appropriate setsockopt()
call with the IP_ADD_MEMBERSHIP option, rather than bind().
您可以使用适当的setsockopt()调用和IP_ADD_MEMBERSHIP选项(而不是bind())来加入任意数量的组播组。
#2
3
You only bind a socket once. Skip the bind the second time and see what happens.
您只绑定一次套接字。第二次跳过绑定,看看会发生什么。
#3
2
bind
to the passive address, i.e. 0.0.0.0 for IPv4 and use ASM or SSM to pull in additional groups, e.g. IP_ADD_MEMBERSHIP
as listed.
绑定到被动地址,即对于IPv4为0.0.0.0,并使用ASM或SSM来引入其他组,例如列出的IP_ADD_MEMBERSHIP。
You can only bind
once.
你只能绑定一次。
#4
2
You can join as many multicast groups you want to on a single socket. See setsockopt(), IP_PKTINFO for a way to recognize which multicast group you are reading data from.
您可以在单个套接字上加入所需数量的多播组。有关识别要从中读取数据的多播组的方法,请参阅setsockopt(),IP_PKTINFO。
#5
0
Yes, it's possible: look on the example in the link (http://www.tenouk.com/Module41c.html) To shorten this up in a few steps:
是的,这是可能的:查看链接中的示例(http://www.tenouk.com/Module41c.html)通过以下几个步骤简化此操作:
- You setsockopt with SO_REUSEADDR
- You bind on INADDR_ANY
- You setsockopt with IP_ADD_MEMBERSHIP on every group you want to receive datagram from.
- It seems to me that using IP_PKTINFO gives an option to distinguish received packets, but sender must take care about preparing them(Setting the source IP for a UDP socket)
你使用SO_REUSEADDR setockopt
您绑定INADDR_ANY
在要从其接收数据报的每个组上使用IP_ADD_MEMBERSHIP setockopt。
在我看来,使用IP_PKTINFO提供了区分收到的数据包的选项,但发送者必须注意准备它们(设置UDP套接字的源IP)
#6
-3
I do not believe it possible to join more than one multicast group on a given socket. The socket is defined by the pairing of the source ip/port and destination ip/port. The operating system would not know what to do with data that comes down from the second ip/port because it would not have a socket to send it to.
我不相信可以在给定套接字上加入多个多播组。套接字由源IP /端口和目标IP /端口的配对定义。操作系统不知道如何处理来自第二个ip / port的数据,因为它没有套接字来发送它。
The bind is necessary to register the connection with the operating system. It's basically like registering a file handle.
绑定是注册与操作系统的连接所必需的。它基本上就像注册文件句柄一样。
The best way to do this would be to create a socket for each multicast group and then call select(). select() will inform you if any socket has data ready for reading.
执行此操作的最佳方法是为每个多播组创建一个套接字,然后调用select()。如果任何套接字已准备好读取数据,select()将通知您。
Check your man pages for more info on socket(), bind(), and select().
有关socket(),bind()和select()的更多信息,请查看手册页。