我正在试图弄清楚如何使用IPV6进行相当于IPV4的广播。
我正在创建一个非阻塞的IPV6 UDP套接字。
从侧面播放我实际上只是在端口12346上发送“FF02 :: 1”。
在听取方面,我发现我需要加入小组,所以我做了以下事情:
ipv6_mreq membership;
memset( &membership.ipv6mr_multiaddr, 0, sizeof( in6_addr ) );
membership.ipv6mr_multiaddr.u.Word[0] = htons( 0xff02 );
membership.ipv6mr_multiaddr.u.Word[7] = htons( 0x0001 );
membership.ipv6mr_interface = 0;
if( enable )
{
if ( 0 != setsockopt( m_Socket, SOL_SOCKET, IPV6_JOIN_GROUP, (char*)&membership, sizeof( ipv6_mreq ) ) )
{
DisplayError();
return false;
}
}
但是setsockopt总是返回“WSAENOPROTOOPT”。为什么?任何人都可以帮我这个吗?我完全失去了。
编辑:我将级别更改为“IPPROTO_IPV6”,但现在我得到了“WSAEINVAL”。
答案 0 :(得分:4)
必须为本地范围的IPv6设置接口,因为地址仅对接口是唯一的。简单来说,地址fe80 :: 1既可以属于eth0也可以属于eth1,但是完全是分开的。
因此,这意味着您需要在支持多播的每个 up 接口上显式发送多播数据包,或者为用户提供指定特定接口的方法。
(编辑)如果它可以帮助你在这里检查多播代码,
http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/
答案 1 :(得分:1)
我认为问题在于你将ipv6mr_interface值保留为零,如果你想使用像ff02 :: 1这样的链接范围多播地址,那就不够了。您需要将ipv6mr_interface值设置为与您希望发送/接收数据包的本地网络接口对应的数字。 (你可以通过调用getaddrinfo()并从你手中的(struct sockaddr_in6 *)读取sin6_addr.s6_addr值来找出当前计算机上可用的接口索引。
(如果此时你正在考虑自己,如果接口零作为“所有接口”设置,它会不会那么容易......是的,它会是。唉,IPv6不这样做由于某种原因:()