基于 IPv6 的 UDP 多播客户端

基于 IPv6 的 UDP 多播客户端

简单的Python UDP服务器:从本地主机以外的客户端接收数据包时遇到问题

我正在尝试通过 ipv6 监听数据报。以下是我感兴趣的消息:

$ sudo tcpdump | grep 20001
[sudo] password for miroslavv: 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:00:59.981338 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 86
13:00:59.981348 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.981733 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 114
13:00:59.981744 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 67
13:00:59.981940 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 60
13:00:59.982276 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982492 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982656 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982974 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 69
13:00:59.982985 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 111
13:00:59.983335 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 152

我的平台是Debian测试。我尝试了蟒蛇例子,它们似乎在同一台机器上完美地相互通信。然而,当服务器配置为侦听上面列出的数据报时,它会挂起recv()

防火墙设置:

$ sudo iptables -L
[sudo] password for miroslavv: 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

我有一个ipv6:

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.42.92  netmask 255.255.248.0  broadcast 192.168.47.255
        inet6 fd01:e671:2015:e3ff:219:fff:fe26:a27e  prefixlen 48  scopeid 0x0<global>
        inet6 fe80::219:fff:fe26:a27e  prefixlen 64  scopeid 0x20<link>
        ether 00:19:0f:26:a2:7e  txqueuelen 1000  (Ethernet)
        RX packets 3360785  bytes 943676498 (899.9 MiB)
        RX errors 0  dropped 6185  overruns 0  frame 0
        TX packets 473236  bytes 77103917 (73.5 MiB)
        TX errors 1  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 140  bytes 7912 (7.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 140  bytes 7912 (7.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

netcat也沉默了:

$ netcat -u -l -p20001

一个奇特的观察结果如下。我设法得到一些 C++ 代码来读取消息如果同时boost::asio从同一个ip和端口读取。如果停止增强轮询,我的代码也会停止接收消息。

我已经尝试了一堆示例 C 程序,但无法从任何人那里接收甚至一个 UDP 数据包:1,2,3,4

这里发生了什么?

答案1

事实上,我错过了加入多播组的机会。有关 ipv6 多播的示例相当稀少,这里是经过测试的代码:

struct addrinfo hint {}, *res;
hint.ai_flags = AI_PASSIVE;
hint.ai_family = AF_INET6;
hint.ai_socktype = SOCK_DGRAM;
getaddrinfo( server._rep.c_str(), std::to_string( port ).c_str(), &hint, &res )
mreq.ipv6mr_multiaddr = reinterpret_cast<  sockaddr_in6* >( res->ai_addr )->sin6_addr;
mreq.ipv6mr_interface if_nametoindex( iface.c_str();
setsockopt( _fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void*)mreq, sizeof( mreq ) )

PS:关于该主题的一些有用资源:

http://www.iitk.ac.in/LDP/HOWTO/Multicast-HOWTO.html#toc6

http://docs.oracle.com/cd/E19253-01/817-4415/sockets-149/index.html

相关内容