Ste*_*mer 3 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)"));
Run Code Online (Sandbox Code Playgroud)
当应用程序关闭时,它关闭套接字
close(fd);
Run Code Online (Sandbox Code Playgroud)
但是,它不执行IP_DROP_MEMBERSHIP
.
是的,Linux 为其先前在特定接口上加入的每个多播组维护一个引用计数,并且当您关闭与请求特定组成员资格的套接字相对应的最后一个文件描述符时,Linux 会检查对该组成员资格的引用计数为空,如果是这种情况,它将在相应的网络接口上发送类型为“离开组”的成员资格报告。
只需执行以下操作即可自行检查:
要么使用您的程序,要么用于socat
请求特定的多播组成员身份。例如:
% socat STDIO UDP4-DATAGRAM:239.101.1.68:8889,ip-add-membership=239.0.1.68:192.168.250.2
Run Code Online (Sandbox Code Playgroud)
(用您的接口之一的地址替换 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
Run Code Online (Sandbox Code Playgroud)最后,嗅探你的网络接口:
# tshark -n -i tun0 -Y igmp
Running as user "root" and group "root". This could be dangerous.
Capturing on 'tun0'
Run Code Online (Sandbox Code Playgroud)
现在,杀死 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
Run Code Online (Sandbox Code Playgroud)此外,您可以尝试同时启动程序的多个实例,您会看到只有当您杀死最新的实例时,Leave group
才会发送消息。您还将看到正在运行的程序的实例数是出现在netstat -gn
.