在一个套接字上订阅多个多播组 (Linux, C)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9243292/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:31:40  来源:igfitidea点击:

Subscribing to multiple multicast groups on one socket (Linux, C)

clinuxnetworkingmulticast

提问by Switch

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。这可能吗?或者我是否需要每组一个套接字然后只使用轮询?

回答by bmargulies

You only bind a socket once. Skip the bind the second time and see what happens.

您只绑定一次套接字。第二次跳过绑定,看看会发生什么。

回答by user207421

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()。

回答by Steve-o

bindto 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_MEMBERSHIPas listed.

bind到被动地址,即 IPv4 的 0.0.0.0 并使用 ASM 或 SSM 拉入其他组,例如IP_ADD_MEMBERSHIP列出的。

You can only bindonce.

你只能bind一次。

回答by ThatsEnough

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 以获取识别您正在读取数据的多播组的方法。

回答by bambo

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) 要通过几个步骤来缩短它:

  1. You setsockopt with SO_REUSEADDR
  2. You bind on INADDR_ANY
  3. You setsockopt with IP_ADD_MEMBERSHIP on every group you want to receive datagram from.
  4. 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)
  1. 你用 SO_REUSEADDR 设置了
  2. 您绑定 INADDR_ANY
  3. 您可以在要从中接收数据报的每个组上使用 IP_ADD_MEMBERSHIP 设置ockopt。
  4. 在我看来,使用 IP_PKTINFO 提供了一个选项来区分接收到的数据包,但发送方必须注意准备它们(为 UDP 套接字设置源 IP

回答by nullptr

In unix based OSes:

在基于 Unix 的操作系统中:

If you need to bind to multicast address, you cannot call bind()more than once. And you will need to bind to multicast address when you expect more than one multicast streams using same destination port and multiple processes running in same device receiving those multicasts.

如果需要绑定到多播地址,则不能bind()多次调用。当您期望使用相同目标端口的多个多播流和在同一设备中运行的多个进程接收这些多播时,您将需要绑定到多播地址。

For example, when you have multicast streams: 239.0.0.1:1234, 239.0.0.2:1234, 239.0.0.3:1234 and 239.0.0.4:1234, and you want to receive 239.0.0.1, 239.0.0.2 in process-A and want to receive 239.0.0.3, 239.0.0.4 in process-B, you cannot accomplish this when both processes A and B running in same device.

例如,当您有多播流:239.0.0.1:1234、239.0.0.2:1234、239.0.0.3:1234 和 239.0.0.4:1234,并且您想接收 239.0.0.1、239.0.0 和 239.0-A 时。想要在进程 B 中接收 239.0.0.3、239.0.0.4,当进程 A 和 B 在同一设备上运行时,您无法完成此操作。