5

我正在研究一些使用 IGMP 加入加入多播组的代码

struct ip_mreq mreq;
inet_pton(AF_INET, group, &mreq.imr_multiaddr.s_addr);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);

if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) < 0)
    throw std::runtime_error(perror("setsockopt(IP_ADD_MEMBERSHIP)"));

当应用程序关闭时,它会关闭套接字

close(fd);

但是,它不执行IP_DROP_MEMBERSHIP.

  • 上游路由器是否会继续将多播传送到我的网络接口?
  • 操作系统(在我的情况下是 Linux)是否足够智能,可以在套接字关闭时为我发送删除会员请求?
4

2 回答 2

6

是的,Linux 为之前在特定接口上加入的每个多播组维护一个引用计数,当您关闭与请求特定组成员身份的套接字对应的最后一个文件描述符时,Linux 会检查该组成员身份的引用计数是否为空,如果是这种情况,它将在相应的网络接口上发送类型为“离开组”的成员资格报告。

只需执行以下操作即可自行检查:

  1. 要么使用您的程序,要么使用socat请求特定的多播组成员资格。例如:

    % socat STDIO UDP4-DATAGRAM:239.101.1.68:8889,ip-add-membership=239.0.1.68:192.168.250.2
    

    (将 192.168.250.2 替换为您的一个接口的地址 - 请注意,在此示例中,具有此地址的接口名为tun0

  2. 现在,查看 Linux 节点上的多播组成员身份:

    % netstat -gn
    IPv6/IPv4 Group Memberships
    Interface       RefCnt Group
    --------------- ------ ---------------------
    lo              1      224.0.0.1
    [...]
    tun0            1      239.0.1.68
    
  3. 最后,嗅探你的网络接口:

    # tshark -n -i tun0 -Y igmp
    Running as user "root" and group "root". This could be dangerous.
    Capturing on 'tun0'
    

    现在,杀死 socat (pkill socat例如 )。您应该会看到由 tshark 编写的以下行:

    7   2.197520 192.168.250.2 -> 224.0.0.22   IGMPv3 40 Membership Report / Leave group 239.0.1.68
    

此外,您可以尝试同时启动程序的多个实例,您会看到只有当您杀死最新的实例时,Leave group才会发送消息。您还将看到正在运行的程序的实例数是出现在netstat -gn.

于 2017-08-01T17:49:03.297 回答
1

上游路由器是否会继续将多播传送到我的网络接口?

除非您的主机中有其他组成员。

操作系统(在我的情况下是 Linux)是否足够智能,可以在套接字关闭时为我发送删除会员请求?

是的。除非您想在套接字上动态更改组,否则您无需担心 IP_DROP_MEMBERSHIP,这非常罕见:我当然从未这样做过。

于 2017-08-04T00:34:19.340 回答