将 UDP 数据报发送到具有多播地址的多个接口

Send UDP datagrams to multiple interfaces with multicast address

我有一台 Windows 11 机器,它有两个网络接口:

  1. 192.168.1.16/24(Wi-Fi:物理以太网连接到外部路由器)
  2. 172.22.112.1/20(vEthernet(默认交换机):来自 Hyper-V 的内部虚拟交换机)

我正在编写一个应通过两个接口发送多播消息的应用程序。

理想情况下,我只想从应用程序发送一次数据,并且数据将在两个接口上结束而无需配置 Windows :) :

s = socket(AF_INET, SOCK_DGRAM, ...)
bind(s, INADDR_ANY,...)
sendto(s, buf, ..., 239.255.0.1, ...)

不幸的是,消息仅通过 Wi-Fi 接口到达。这个接口是由路由决定的table,我猜。

PS>netstat -rn
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.1.1     192.168.1.16     50
...
        224.0.0.0        240.0.0.0         On-link      172.22.112.1   5256
        224.0.0.0        240.0.0.0         On-link      192.168.1.16    306
...

在这种情况下,它只转到接口 192.168.1.16,因为度量是匹配路由的最小值。如果两个接口都加入了多播组,也会发生这种情况。

PS> netsh int ip show joins
Interface 1: Wi-Fi

Scope       References  Last  Address
----------  ----------  ----  ---------------------------------
...
0                    1  Yes   239.255.0.1
0                    3  Yes   239.255.255.250
...
Interface 2: vEthernet (Default Switch)

Scope       References  Last  Address
----------  ----------  ----  ---------------------------------
...
0                    1  Yes   239.255.0.1
0                    4  Yes   239.255.255.250

我找到的一个解决方案是像这样发送两次数据包:

setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, 192.168.1.16, ...)
sendto(s, buf, ..., 239.255.0.1, ...)
setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, 172.22.112.1, ...)
sendto(s, buf, ..., 239.255.0.1, ...)

有没有办法在没有setsockopt IP_MULTICAST_IF循环的情况下通过所有接口发送多播消息?也许我错过了一些套接字选项?

或者如果在代码中不可行,有没有办法配置Windows将数据包转发到所有接口?

最初我认为多播会转到所有加入的接口,Windows 处理正确吗?

数据包只会从一个接口发出,无论是单播、多播还是广播。

正确的处理方法正如您所发现的那样,即在发送数据包之前在套接字上设置 IP_MULTICAST_IF 选项。