2017-08-01 54 views
1

我工作的一些代码,连接使用IGMP多播组加入如果在关闭套接字之前未发送IP_DROP_MEMBERSHIP,会发生什么情况?

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)是否足够聪明,可以为我发送drop membership request?

回答

3

是,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的输出中的数字。

+0

感谢您的支持!你有什么样的参考,我可以证实这一点吗? –

+0

是的,我已经更新了我的答案,所以你可以自己尝试。此外,您可以查看名为src/net/ipv4/igmp.c的内核源文件,这是维护refcnt并在从非null更改为null时发送'leave group'的代码(此文件用于IPv4组仅限会员) –

+0

非常详细的回复谢谢! –

1

将组播继续由上游路由器传送到我的网络接口?

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

当套接字关闭时,操作系统(在我的情况下为Linux)是否足够聪明,可以为我发送drop membership请求?

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

相关问题