如果我在关闭套接字之前没有发送IP_DROP_MEMBERSHIP会发生什么?

时间:2017-08-01 15:52:48

标签: c++ sockets multicast igmp

我正在研究一些使用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)是否足够聪明,可以在套接字关闭时为我发送丢弃成员资格请求?

2 个答案:

答案 0 :(得分:4)

是的,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
    
  4. 此外,您可以尝试同时启动程序的多个实例,您将看到只有在您终止最新实例时才会发送Leave group消息。您还将看到正在运行的程序的实例数是netstat -gn第2列的输出中显示的数字。

答案 1 :(得分:1)

  

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

除非您的主持人中有其他小组成员。

  

操作系统(在我的情况下是Linux)是否足够聪明,可以在套接字关闭时为我发送丢弃成员资格请求?

是。除非你想在套接字上动态更改组,否则你不必担心IP_DROP_MEMBERSHIP,这是非常罕见的:我当然从来没有这样做过。