将 UDP 数据报发送到具有多播地址的多个接口
Send UDP datagrams to multiple interfaces with multicast address
我有一台 Windows 11 机器,它有两个网络接口:
192.168.1.16/24
(Wi-Fi:物理以太网连接到外部路由器)
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
选项。
我有一台 Windows 11 机器,它有两个网络接口:
192.168.1.16/24
(Wi-Fi:物理以太网连接到外部路由器)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
选项。