C++ 在具有多个接口的linux主机上接收多播

C++ 在具有多个接口的linux主机上接收多播,c++,c,linux,networking,multicast,C++,C,Linux,Networking,Multicast,我有一台运行Ubuntu 16.04的主机,通过主要有线网络接口连接到一个网络,并通过USB到以太网适配器连接到另一个网络。使用tcpdump,我能够在两个网络接口上验证传入的多播数据包。但是,我的应用程序没有从辅助接口接收任何多播数据。如果我断开与主接口的电缆连接,然后重新启动应用程序,那么我确实会从辅助接口接收数据。只有在两个接口都连接的情况下,应用程序才不会从辅助接口接收信息。我发现USB到以太网适配器存在类似问题Raspberry Pi Zero无法响应mDNS查询。要确定您的问题是否相

我有一台运行Ubuntu 16.04的主机,通过主要有线网络接口连接到一个网络,并通过USB到以太网适配器连接到另一个网络。使用tcpdump,我能够在两个网络接口上验证传入的多播数据包。但是,我的应用程序没有从辅助接口接收任何多播数据。如果我断开与主接口的电缆连接,然后重新启动应用程序,那么我确实会从辅助接口接收数据。只有在两个接口都连接的情况下,应用程序才不会从辅助接口接收信息。

我发现USB到以太网适配器存在类似问题Raspberry Pi Zero无法响应mDNS查询。要确定您的问题是否相同,您的应用程序是否在运行tcpdump的同时正确接收多播流量?在无混杂模式下运行tcpdump是否看不到多播流量

如果你的答案都是肯定的,那么我找到的解决办法就是简单地将eth0-promisc设置为启用ip链接。我不知道这是一个硬件错误,我使用的是Kontron DM9601适配器,ID为0FE6:9700,还是一个驱动程序错误,但不管怎样,启用混杂模式似乎可以修复我的多播接收。或者,您可以尝试更好的USB到以太网适配器。

ip\u mreq结构作为ip\u添加成员身份套接字选项的选项值传递,以加入多播组。来自Linux文档项目:

第一个成员imr_multiaddr持有您想要加入的组地址。请记住,成员身份也与接口相关联,而不仅仅与组相关联。这就是您必须为第二个成员提供值的原因:imr_接口。这样,如果您在多宿主主机中,您可以在多个接口中加入同一组。您可以始终在Dr_ANY中使用通配符地址填充最后一个成员,然后内核将处理选择接口的任务

IP_MULTICAT_IF socket选项也适用于多主机主机,用于为通过套接字发送的多播数据设置出站接口。有关这些套接字选项、ip_mreq结构和较新的ip_mreqn结构的更多信息,请参见

对于在多宿主主机上使用Boost的用户,您需要使用本机句柄在特定接口上加入组。从Ubuntu 16.04上运行的Boost 1.58开始,套接字选项抽象ip::multiast::join_group在内核选择的接口上加入组,并且不允许开发人员指定接口。套接字选项抽象ip::multicast::outbound_接口控制出站接口,但不影响套接字在哪个接口上接收

以下是基于本地接口IP地址在特定接口上加入组的代码示例:

struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(discovery_ip);
mreq.imr_interface.s_addr = inet_addr(local_interface_ip);
if(setsockopt(socket_.native_handle(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
    ... handle error ...
}

您已经在多宿主主机中通过每个接口依次迭代发出联接的接口。@EJP感谢您的指针。这解决了我的问题!非常感谢。我有相同的DM9601适配器,此更改修复了pi无法响应mDNS查找的问题。