Linux VS Windows 上的 UDP 多播差异

UDP Multicast differences on linux VS windows

本文关键字:多播 UDP 上的 VS Windows Linux      更新时间:2023-10-16

以下示例程序创建两个 udp 套接字,将它们连接到两个不同的多播组,然后将它们绑定到同一端口上的INET_ANY(使用 SO_REUSEADDR)。

出于说明目的,程序还会将数据报发送到两个多播组之一。

#include <iostream>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/ip/multicast.hpp>
int main()
{
namespace ip = boost::asio::ip;
using udp = ip::udp;
boost::asio::io_context context;
const auto addr1 = ip::address::from_string("224.111.0.0");
const auto addr2 = ip::address::from_string("224.112.0.0");
const unsigned short port = 10001;
udp::socket receiver1( context, udp::v4() );
udp::socket receiver2( context, udp::v4() );
receiver1.set_option( ip::multicast::join_group(addr1) );
receiver2.set_option( ip::multicast::join_group(addr2) );
receiver1.set_option( udp::socket::reuse_address(true) );
receiver2.set_option( udp::socket::reuse_address(true) );
receiver1.non_blocking(true);
receiver2.non_blocking(true);
receiver1.bind( udp::endpoint(ip::address_v4::any(), port ) );
receiver2.bind( udp::endpoint(ip::address_v4::any(), port ) );
char data[1] = {};
// Dummy sender
udp::socket sender( context, udp::v4() );
sender.send_to( boost::asio::buffer(data), udp::endpoint(addr2,port) );
udp::endpoint sender_ep;
boost::system::error_code ec;
std::size_t count;
count = receiver1.receive_from(boost::asio::buffer(data), sender_ep, 0, ec );
std::cout << "Receive1 : " << count << " from: " << sender_ep << std::endl;
count = receiver2.receive_from(boost::asio::buffer(data), sender_ep, 0, ec );
std::cout << "Receive2 : " << count << " from: " << sender_ep << std::endl;
}

在我的 linux 机器(内核 5.1.15)上,输出是:

Receive1 : 1 from: 192.168.1.67:37165
Receive2 : 1 from: 192.168.1.67:37165

也就是说,两个套接字接收到发送到224.112.0.0的单个数据报,即使receiver1没有加入该组。

在我的 Windows 7 x64 虚拟机上测试的为 Windows 编译的相同代码输出:

Receive1 : 0 from: 0.0.0.0:0
Receive2 : 1 from: 192.168.56.101:54670

也就是说,只有加入组的套接字224.112.0.0.接收数据报。

问题:

  • 这种差异是有意的吗?如果是这样,它是否记录在任何地方?
  • 如果我无法修改接收应用程序,是否有某种方法,通过配置发送套接字或操作系统配置,来模仿我的 Linux 机器上的Windows行为?

一些背景:

我正在尝试使用 wine 在 Linux 上运行第 3 方窗口二进制文件的两个实例。我认为每个实例都按照示例代码的行执行一些操作(确切的组播组是可配置的,但不是它使用的端口)。Wine 大约将 winsock 转换为 posix 1 比 1,因此在 wine 上运行的程序的行为方式与本机 Linux 上的示例相同。 目前我无法单独控制这两个实例,因为两者都接收相同的数据。

尝试更改绑定以使用多播地址而不是"any"。

请参阅绑定多播 (UDP) 套接字意味着什么?