关于 IP_ADD_MEMBERSHIP 的文档说:
IP_ADD_MEMBERSHIP (since Linux 1.2) Join a multicast group. Argument is an ip_mreqn structure.
struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast group address */ struct in_addr imr_address; /* IP address of local interface */ int imr_ifindex; /* interface index */ }; imr_multiaddr contains the address of the multicast group the appli‐ cation wants to join or leave. It must be a valid multicast address (or setsockopt(2) fails with the error EINVAL). imr_address is the address of the local interface with which the system should join the multicast group; if it is equal to INADDR_ANY, an appropriate inter‐ face is chosen by the system. imr_ifindex is the interface index of the interface that should join/leave the imr_multiaddr group, or 0 to indicate any interface.
所以我有一个接口(interface)“eth0”,IP 为 192.168.1.5。我想将此接口(interface)加入多播组 225.1.1.1。我对如何正确设置 ip_mreqn 结构有点困惑?我找到了 2 种可能的方法:
1.
ip_mreqn group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;
2.
ip_mreqn group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");
第三种方法是使用 SO_BINDTODEVICE 套接字选项。
我的问题是。
1) 将特定接口(interface)加入多播组的正确方法是什么?
2) imr_address 和 imr_ifindex 的功能区别是什么?
3) 选项 SO_BINDTODEVICE 有何用处?
编辑:我做了一些研究。
假设我有两个网络接口(interface):eth0 的 ip 192.168.1.5 和 eth1 的 ip 192.168.1.255 我在 eth0 上接收多播 ip 192.168.1.5。
这些方式工作正常(我在 eth0 上收到多播消息):
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;
或
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");
或者显然
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth0");
甚至
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth0");
这些方法不会(我不会在 eth0 上收到多播消息):
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth1");
和
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth1");
最佳答案
我一直使用旧的 struct ip_mreq
而不是 struct ip_mreqn
,因为两者都受支持。此结构没有索引字段,因此您需要设置的内容不那么模糊。
struct ip_mreq
{
/* IP multicast address of group. */
struct in_addr imr_multiaddr;
/* Local IP address of interface. */
struct in_addr imr_interface;
};
然后你可以这样设置它:
struct ip_mreq group;
group.imr_multiaddr.s_addr = inet_addr("225.1.1.1");
group.imr_interface.s_addr = inet_addr("192.168.1.5");
关于C++在特定接口(interface)上接收多播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48624503/