多进程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广播包绑定到一个网卡的主要内容,如果未能解决你的问题,请参考以下文章

多网卡UDP多播的问题,指定某一网卡加入多播,而非系统默认

linux 多进程绑定问题

多网卡绑定bonding

Centos7 多网卡抓包可以抓到UDP但程序recvfrom不到

多网卡绑定

Linux网络 - 数据包在内核中接收和发送的过程(转)