8

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

4

2 回答 2

4

必须为本地范围的 IPv6 设置接口,因为地址仅对接口是唯一的。简单来说,地址 fe80::1 可以同时属于 eth0 和 eth1,但它们是完全独立的。

因此,这意味着您需要在每个支持多播的上行接口上显式发送多播数据包,或者为用户提供一种指定特定接口的方法。

(编辑)如果有帮助,您可以在此处查看多播代码,

http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/

于 2010-06-26T04:10:46.860 回答
1

我认为问题在于您将 ipv6mr_interface 值保留为零,如果您想使用像 ff02::1 这样的链接范围多播地址,这还不够好。您需要将 ipv6mr_interface 值设置为与您希望在其上发送/接收数据包的本地网络接口对应的数字。(您可以通过调用 getaddrinfo() 并从它交给您的 (struct sockaddr_in6 *) 中读取 sin6_addr.s6_addr 值来找出当前计算机上可用的接口索引)

(如果此时您正在考虑自己,如果接口零充当“所有接口”设置会不会容易得多......是的,会的。唉,IPv6 出于某种原因不这样做:( )

于 2010-06-21T20:53:24.610 回答