多进程UDP广播包绑定到一个网卡
Posted
技术标签:
【中文标题】多进程UDP广播包绑定到一个网卡【英文标题】:UDP broadcast packets in multiple processes bound to one NIC 【发布时间】:2015-10-31 10:04:06 【问题描述】:我正在玩一个 .NET 对等应用程序的想法,其中一个对等点使用 UDP 数据包在子网上宣传它的存在。然后,任何侦听对等方将从数据包中获取足够的信息,以使用 TCP 与广告商建立直接通信通道。
似乎需要将广播数据包定向到特定端口号,并且为了接收数据包,对等方需要绑定到 IPAddress.Any 上的该端口。
使用这种设计,是否可以运行多个绑定到同一个 NIC 的对等点?我只是得到一个 SocketException “每个套接字地址(协议/网络地址/端口)通常只允许使用一次”,直到我添加以下代码行:
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
设置此选项有什么影响?
【问题讨论】:
【参考方案1】:我不确定您是否可以通过广播做到这一点。另一方面,这是链路本地多播的标准做法。由于 IPv6 多播 API 比 IPv4 API 设计得更好,我建议使用 IPv6 本地链接——您不需要全局 IPv6 地址和路由,即使没有 IPv6 连接,您的应用程序也可以在任何现代系统上运行。
首先,选择一个随机的 IPv6 链路本地多播组,ff02::/16
中的任何内容都可以(有关详细信息,请参阅 RFC 4291 第 2.7 节)。然后,您的应用程序应该:
-
在套接字上设置
SO_REUSEADDR
;
绑定到您选择的端口;
将IPV6_MULTICAST_LOOP
设置为0,IPV6_MULTICAST_HOPS
设置为1;
使用IPV6_JOIN_GROUP
订阅多播组;
向组播组发送UDP数据包,出接口的接口ID为sin6_scope_id
。
通过检查sin6_scope_id
确定接收数据包的传入接口。
这在 RFC 3493 第 5.2 节中有详细描述。
【讨论】:
您的示例仍然使用 UDP 并使用 ReuseAddress 选项绑定到同一端口。当然,相同的含义将适用于我们的两个示例,但是对于您的示例,我需要另外学习 IPv6 以及多播的工作原理。还是在适配器级别有区别处理 IPv4 UDP 数据包和 IPv6 UDP 数据包的东西? 对于 IPv4 广播,您需要使用不同的技术来 (1) 复制接收到的数据包以获取每个进程的副本,以及 (2) 指定数据包的传出接口你发送的。后者很容易,我不知道如何做前者。发现后请补充答案。以上是关于多进程UDP广播包绑定到一个网卡的主要内容,如果未能解决你的问题,请参考以下文章