如果在关闭套接字之前未发送IP_DROP_MEMBERSHIP,会发生什么情况?
问题描述:
我工作的一些代码,连接使用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?
答
是,Linux维护了它在特定接口上先前加入的每个组播组的引用计数,而当你关闭相应的插口,要求特定组成员的最后一个文件描述符,Linux的检查,如果此组成员资格的引用计数为空,如果是这种情况,则会在相应的网络接口上发送类型为“离开组”的成员资格报告。
只要做到以下自行检查:
-
要么使用你的程序,或者使用
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
) -
现在,看看组播组会员对你的Linux节点:
% netstat -gn IPv6/IPv4 Group Memberships Interface RefCnt Group --------------- ------ --------------------- lo 1 224.0.0.1 [...] tun0 1 239.0.1.68
-
最后,嗅探网络接口:
# 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
的输出中的数字。
答
将组播继续由上游路由器传送到我的网络接口?
不除非有您的主机其他组成员。
当套接字关闭时,操作系统(在我的情况下为Linux)是否足够聪明,可以为我发送drop membership请求?
是的。除非您想在套接字上动态更改组,否则不必担心IP_DROP_MEMBERSHIP,这很罕见:我从来没有这样做过。
感谢您的支持!你有什么样的参考,我可以证实这一点吗? –
是的,我已经更新了我的答案,所以你可以自己尝试。此外,您可以查看名为src/net/ipv4/igmp.c的内核源文件,这是维护refcnt并在从非null更改为null时发送'leave group'的代码(此文件用于IPv4组仅限会员) –
非常详细的回复谢谢! –