IPV6链接本地多播

时间:2010-06-18 08:44:11

标签: c++ ipv6 multicast link-local

我正在试图弄清楚如何使用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”。

2 个答案:

答案 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不这样做由于某种原因:()