gpt4 book ai didi

c++ - linux VS windows 上的 UDP 组播差异

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:13:37 25 4
gpt4 key购买 nike

下面的示例程序创建了两个 udp 套接字,将它们加入两个不同 多播组,然后将它们绑定(bind)到同一端口 上的 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 编译的相同代码,在我的 windows 7 x64 虚拟机上测试,输出:

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 方 Windows 二进制文件的两个实例。我认为每个实例都按照示例代码执行某些操作(确切的多播组是可配置的,但不是它使用的端口)。 Wine 大致将 winsock 转换为 posix 1 对 1,因此在 wine 上运行的程序的行为方式与 native linux 上的示例相同。目前我无法单独控制这两个实例,因为它们接收相同的数据。

最佳答案

尝试更改您的绑定(bind)以使用多播地址而不是“任何”。

参见 What does it mean to bind a multicast (UDP) socket?

关于c++ - linux VS windows 上的 UDP 组播差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57135767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com