如何在 C# 中使用 MLDv2(IPv6 组播)
In IPv4, [Version 3 of IGMP adds support for "source filtering", that is, the ability for a system to report interest in receiving packets *only* from specific source addresses.][1]
我在 C# 应用程序中使用 IGMPv3 来支持此行为。 这是我的做法。
我现在正在我的应用程序中添加对 IPv6 的支持,我需要获得与 IPv4 中相同的行为。据我所知,IPv6 中 IGMPv3 的等效协议是 MLDv2。有人知道如何在 C# 中使用 Socket 实现这一点吗?
谢谢!
In IPv4, [Version 3 of IGMP adds support for "source filtering", that is, the ability for a system to report interest in receiving packets *only* from specific source addresses.][1]
I am using IGMPv3 in a C# application to support this behaviour. Here is how I do it.
I am now in the process to add support to IPv6 in my application and I need to get the same behaviour as in IPv4. From what I've read, the equivalent protocol to IGMPv3 in IPv6 is MLDv2. Has someone any idea on how to implement this in C# with Socket?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
RFC3678 协议独立 API 仅在 Vista+ 中可用,这可能解释了问题。
如果 C# 运行时完全支持 IPv6,则必须尝试匹配 GROUP_REQ 或 GROUP_SOURCE_REQ 结构。 SSM 没有与 IPv4 API 相匹配的 IPv6 特定 API,因为开发人员最终放弃了 API 的愚蠢重复,并最终选择了一个超级集。
不幸的是,C# 很可能实现 ipv6_mreq 对于
AddMembership
和AddSourceMembership
失败。该文档完全缺乏细节。C# 中未定义所需的所有
SocketOptionName
值:The RFC3678 protocol independent API is only available in Vista+ which might explain the problem.
If C# runtime does fully support IPv6 you will have to try to match the GROUP_REQ or GROUP_SOURCE_REQ structures. There is no IPv6 specific API for SSM matching the IPv4 API because developers finally abandoned the inane duplication of APIs and finally settled on the one super set.
It is unfortunately likely that C# implements ipv6_mreq for
AddMembership
andAddSourceMembership
fails. The documentation is completely absent on detail.All the
SocketOptionName
values required are not defined in C#:为了跟进 Steve-o 的答案,即使 System.Net.Sockets.SocketOptionName 枚举没有通过直接转换数字来定义所需的选项,仍然可以在 C# 中对 IPv6 进行源过滤。
即使选项未被识别,套接字的函数 SetSocketOption 也会让调用转到“Windows 套接字”。真正的困难在于需要与选项一起发送的数据结构本身。
要设置源过滤,数据结构必须如下所示: group_source_req。前面的结构使用 sockaddr_storage 通常位于与 sockaddr_in 和 sockaddr_in6。要复制此行为,我们可以定义相同的结构,如下所示:
您现在可以通过执行以下操作创建 sockaddr_in6:
现在可以使用提供的解决方案提取 sockaddr_in6 的字节 此处并直接复制到之前创建的 sockaddr_storage 中:
现在您有了 sockaddr_storage,您可以将其分配给 group_source_req 并像我们之前所做的那样提取 group_source_req 的数据,并在设置选项时使用它作为值。
To follow up on the answer of Steve-o, it is still possible to do source filtering in IPv6 in C# even if the System.Net.Sockets.SocketOptionName enumeration doesn't define the required options by casting the number directly.
The function SetSocketOption of the socket will let the call go to the "windows socket" even if the option is not recognized. The real struggle becomes the data structure itself that needs to be sent along side the option.
To set source filtering the data structure must be like this one: group_source_req. The previous struct is using a sockaddr_storage that is usually inside a union with sockaddr_in and sockaddr_in6. To replicate this behavior we can define the same structs like this:
You can now create a sockaddr_in6 by doing this:
The bytes of the sockaddr_in6 can now be extracted by using the solution provided here and copied directly into a previously created sockaddr_storage:
Now that you have a sockaddr_storage you can assign it to group_source_req and extract the data of the group_source_req like we did earlier and use this as the value when you set the option.