在不同接口上接收具有相同源地址的不同组播

时间:2016-03-21 13:03:39

标签: c linux sockets udp multicast

在具有多个网络接口的系统上,我可以在不同的网络上使用相同的多播地址和端口组合,并且具有不同的数据。我希望能够使用多个网卡连接它们,并在每个接口上接收不同的数据。

为此,我使用IP_MULTICAST_IF选项绑定到我想要接收的界面:

ip_mreqn mreqn;
memset(&mreqn, 0, sizeof (ip_mreqn));
mreqn.imr_multiaddr.s_addr = inet_addr(mc);
mreqn.imr_address.s_addr = INADDR_ANY;
mreqn.imr_ifindex = if_nametoindex(device);
if (setsockopt(mct->fd, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn)) < 0) {
  perror("setsockopt multicast if");
  return 1;
}

并确保仅通过设置具有相同结构的IP_ADD_MEMBERSHIP在该界面上发送加入请求:

if (setsockopt(mct->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, sizeof(mreqn)) < 0) {
  perror("setsockopt add membership");
  return 1;
}

虽然IP_ADD_MEMBERSHIP代码有效(加入请求仅在指定的接口上发送),但IP_MULTICAST_IF却没有。相反,一旦它能够在任何接口上加入多播,我就会通过所有套接字接收相同的数据,即使它们设置的imr_ifindex不同。

1 个答案:

答案 0 :(得分:1)

IP_MULTICAST_IF ioctl不控制传入选择,它为其传出的组播数据包设置套接字的默认接口。

IP_ADD_MEMBERSHIP是配置传入多播的唯一机制,它创建的成员资格是针对整个主机的,主机不根据其请求的成员资格定制传递到各个套接字。 (您可以使用if(moment.version.split('.')[1] > 12) { moment.updateLocale('de',{ monthsShort:'Jan_Febr_Mrz_Apr_Mai_Jun_Jul_Aug_Sept_Okt_Nov_Dez'.split('_') }); } moment('3/Okt/16','D/MMM/YY').format() //"2016-10-03T00:00:00-07:00" 观察主机成员身份,并且引用计数用于确定主机何时可以停止观察,但不会使用哪个套接字正在接收扇出。如果您具有来自任何套接字的匹配成员资格,则全部产生适用netstat -gn的套接字将开始接收该多播,即使它们从未使用过bind(2)。)

通过更改系统设置来区分这些数据包的常用方法是使用辅助数据在套接字上接收它们以识别其接口。在Linux上,此IP_ADD_MEMBERSHIP中使用IP_PKTINFO完成此辅助数据设置。