【问题标题】:IPV6 link local multicastingIPV6 链路本地组播
【发布时间】:2011-03-05 08:06:26
【问题描述】:

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

【问题讨论】:

  • @bdonlan:干杯。是自己做的,但忘了:)

标签: c++ ipv6 multicast link-local


【解决方案1】:

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

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

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

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

【讨论】:

  • 你是说我需要绑定到地址 fe80::1 / 随机端口,然后再执行 IPV6_JOIN_GROUP?
  • 运行 GetAdapterAddresses() 的输出,并为每个具有 IPv6 地址的唯一接口索引调用 IPV6_JOIN_GROUP。
  • 其实我在加入小组之前就绑定了,加入过程很好......那太完美了:)
  • 希望 bdonlan 会奖励你,因为在我看来这是更有帮助的回应 :)
  • @bdonlan:不,唉,赏金的延迟规则更改意味着您需要明确选择它,除非 Steve-o 的回答得到 2 票赞成:(
【解决方案2】:

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

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

【讨论】:

  • 唉,在 windows 下我看到我的主适配器的区域索引是 5。所以我尝试了那个索引。我也是1,还是没有运气……接口索引和区域索引一样吗?
  • 我 99% 确定区域索引和接口索引是一回事;所以可能还有其他问题。在 Windows 下,您可以调用 GetAdaptersAddresses() 来获取每个适配器的 PIP_ADAPTER_ADDRESSES 结构的 Ipv6IfIndex 字段。 GetAdaptersAddresses() 比 Posix 的 getaddrinfo() 函数更有趣...查看以下文件的第 1034-1124 行(尤其是第 1097 行)以了解我对该函数的用法:www.lcscanada.com/muscle/muscle/ util/NetworkUtilityFunctions.cpp
  • 那不是问题所在。一定有什么我错过了。区域索引确实对应于 ifindex。事实上,只是为了测试我的理智,我只是在循环中尝试了从 1 到 50 的每个区域索引,但我仍然得到一个“WSAEINVAL”。
  • 啊,还有一件事:在 Windows 下,您必须在将套接字添加到多播组之前将其绑定到端口。 (这个要求似乎是 Windows 特有的东西;Linux 和 MacOS/X 不关心绑定和组加入之间的顺序)
  • @Jeremy:我知道 IPPROTO_IPV6 ......早期的错误。在尝试添加到多播组之前,我确实将它绑定到端口。如果这对你有任何影响,我会从 Mac OSX 和 iPhone 收到同样的错误!
猜你喜欢
  • 2011-08-10
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 1970-01-01
相关资源
最近更新 更多