【问题标题】:UDP Multicast differences on linux VS windowslinux VS windows上的UDP多播差异
【发布时间】:2019-07-21 18:07:08
【问题描述】:

以下示例程序创建两个 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 编译的相同代码,在我的 windows 7 x64 虚拟机上测试,改为输出:

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

即只有加入组224.112.0.0.的socket才能接收到数据报。

问题:

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

一些上下文:

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

【问题讨论】:

  • 这是Linux中的一个错误,但毫无疑问他们有一些解释。

标签: c++ linux udp multicast winsock2


【解决方案1】:

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

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

【讨论】:

  • 但仅在 Linux 上,这是他们的另一个错误功能。不能绑定其他平台的组播地址。
  • 我无权访问绑定套接字的代码。我知道,如果我绑定到多播地址,两个平台上的一切都可以正常工作,但不幸的是我不能这样做。
猜你喜欢
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 2015-04-17
  • 2018-01-14
  • 2021-04-12
  • 1970-01-01
相关资源
最近更新 更多