首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++在特定接口上接收组播

C++在特定接口上接收组播
EN

Stack Overflow用户
提问于 2018-02-05 14:13:33
回答 2查看 2.3K关注 0票数 3

IP_ADD_MEMBERSHIP上的医生说:

IP_ADD_MEMBERSHIP (自Linux1.2)加入多播组。参数是一个ip_mreqn结构。 结构ip_mreqn { struct in_addr imr_multiaddr;/* IP组播组地址*/ struct in_addr imr_address;本地接口*/ int imr_ifindex的/* IP地址;/*接口索引*/ };imr_multiaddr包含应用程序希望加入或离开的多播组的地址。它必须是一个有效的多播地址(或者setsockopt(2)由于错误EINVAL而失败)。imr_address是系统应该加入多播组的本地接口的地址;如果它等于INADDR_ANY,则由系统选择合适的接口。imr_ifindex是接口的接口索引,应该加入/离开imr_multiaddr组,或者0来指示任何接口。

因此,我有一个接口"eth0“与ip 192.168.1.5。我想加入这个接口到多播组225.1.1.1。我有点困惑如何正确地设置ip_mreqn结构?我找到了两种可能的方法:

1.

代码语言:javascript
复制
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.

代码语言:javascript
复制
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)将特定接口连接到组播组的正确方法是什么?

( 2) imr_address与imr_ifindex的功能差异是什么?

3)如何使用SO_BINDTODEVICE选项?

编辑:,我做了一些研究。

假设我有两个网络接口: ip 192.168.1.5的eth0和ip 192.168.1.255的eth1,ip 192.168.1.5在eth0上接收组播。

这些方法是正确地工作(我在eth0上获得多播消息):

代码语言:javascript
复制
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = 0;

代码语言:javascript
复制
group.imr_address.s_addr = htonl(INADDR_ANY);
group.imr_ifindex = if_nametoindex("eth0");

或者很明显

代码语言:javascript
复制
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth0");

甚至

代码语言:javascript
复制
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth0");

不使用的方式(我在eth0上没有得到多播消息):

代码语言:javascript
复制
group.imr_address.s_addr = inet_addr("192.168.1.5");
group.imr_ifindex = if_nametoindex("eth1");

代码语言:javascript
复制
group.imr_address.s_addr = inet_addr("192.168.1.255");
group.imr_ifindex = if_nametoindex("eth1");
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-05 21:58:10

我一直使用旧的struct ip_mreq而不是struct ip_mreqn,因为两者都是受支持的。这个结构没有索引字段,因此它对于需要设置的内容不那么含糊。

代码语言:javascript
复制
struct ip_mreq
  {
    /* IP multicast address of group.  */
    struct in_addr imr_multiaddr;

    /* Local IP address of interface.  */
    struct in_addr imr_interface;
  };

然后,您将其设置为:

代码语言:javascript
复制
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");
票数 1
EN

Stack Overflow用户

发布于 2021-07-28 01:31:30

ip_mreqn用于在linux/net/ipv4/igmp.c(Linux5.13)的内核源代码中查找网络接口设备,如下所示。

代码语言:javascript
复制
static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
{
    struct net_device *dev = NULL;
    struct in_device *idev = NULL;

    if (imr->imr_ifindex) {
        idev = inetdev_by_index(net, imr->imr_ifindex);
        return idev;
    }
    if (imr->imr_address.s_addr) {
        dev = __ip_dev_find(net, imr->imr_address.s_addr, false);
        if (!dev)
            return NULL;
    }

    if (!dev) {
        struct rtable *rt = ip_route_output(net,
                            imr->imr_multiaddr.s_addr,
                            0, 0, 0);
        if (!IS_ERR(rt)) {
            dev = rt->dst.dev;
            ip_rt_put(rt);
        }
    }
    if (dev) {
        imr->imr_ifindex = dev->ifindex;
        idev = __in_dev_get_rtnl(dev);
    }
    return idev;
}

imr->imr_ifindex首先用于搜索设备。如果未找到,则使用imr->imr_address

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48624503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档