我正在尝试通过 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