代码之家  ›  专栏  ›  技术社区  ›  Goz

IPv6链路本地多播

  •  7
  • Goz  · 技术社区  · 14 年前

    我正试图弄明白如何使用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 回复  |  直到 14 年前
        1
  •  4
  •   Steve-o    14 年前

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

    所以这意味着您需要在 向上的 支持多播的接口,或为用户提供指定特定接口的方法。

    (编辑)如果它有助于您在此处签出多播代码,

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

        2
  •  1
  •   Jeremy Friesner    14 年前

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

    (如果在这一点上,你在想自己,如果接口0作为一个“所有接口”的设置会不会简单得多…是的,会的。唉,ipv6不这么做是有原因的:()