【发布时间】: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