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

只愿长相守 提交于 2019-12-03 19:34:32

问题


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?


回答1:


You can join as many multicast groups as you like, using the appropriate setsockopt() call with the IP_ADD_MEMBERSHIP option, rather than bind().




回答2:


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




回答3:


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.

You can only bind once.




回答4:


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.




回答5:


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:

  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)



回答6:


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.

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.

Check your man pages for more info on socket(), bind(), and select().



来源:https://stackoverflow.com/questions/9243292/subscribing-to-multiple-multicast-groups-on-one-socket-linux-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!