IPv6链路本地组播
我正在尝试弄清楚如何使用 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”。
I'm trying to figure out how to do the equivalent of an IPV4 broadcast using IPV6.
I'm creating a non-blocking IPV6 UDP socket.
From the side broadcasting i'm literally just doing a sendto "FF02::1" on port 12346.
On the listen side I discovered I need to join the group so I did the following:
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;
}
}
However setsockopt always returns "WSAENOPROTOOPT". Why? Can anyone help me on this one? I'm at a complete loss.
Edit: I change the level to "IPPROTO_IPV6" but now I get a "WSAEINVAL".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该接口必须设置为本地范围的 IPv6,因为地址仅对于该接口是唯一的。简单来说,地址 fe80::1 可以同时属于 eth0 和 eth1,但完全独立。
因此,这意味着您需要在每个支持多播的up接口上显式发送多播数据包,或者为用户提供指定特定接口的方法。
(编辑)如果有帮助,您可以在此处查看多播代码,
http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/
The interface must be set for locally scoped IPv6 because the addresses are only unique to the interface. In simpler terms the address fe80::1 can belong to both eth0 and eth1 but are completely separate.
So this means you need to explicitly send a multicast packet on every up interface that supports multicast, or provide the user with a means of specifying a particular interface.
(edit) If it helps you can check out multicast code here,
http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/
我认为问题在于您将 ipv6mr_interface 值保留为零,如果您想使用像 ff02::1 这样的链路范围多播地址,这还不够好。您需要将 ipv6mr_interface 值设置为与您希望发送/接收数据包的本地网络接口对应的编号。 (您可以通过调用 getaddrinfo() 并从它交给您的 (struct sockaddr_in6 *) 中读取 sin6_addr.s6_addr 值来找出当前计算机上可用的接口索引)
(如果此时您正在考虑对你自己来说,如果接口零充当“所有接口”设置,不是会容易得多吗……是的,由于某种原因,IPv6 不会这样做:( )
I think the problem is that you are leaving the ipv6mr_interface value at zero, which isn't good enough if you want to use a link-scope multicast address like ff02::1. You need to set the ipv6mr_interface value to the number corresponding with the local network interface you want the packets to be sent/received on. (You can find out what interface indices are available on the current computer by calling getaddrinfo() and reading the sin6_addr.s6_addr values out of the (struct sockaddr_in6 *)'s that it hands to you)
(If at this point you are thinking to yourself, wouldn't it be so much easier if interface zero acted as an "all interfaces" setting... yes, it would be. Alas, IPv6 doesn't do that for some reason :( )