OSX上的Boost ASIO多播失败

Boost ASIO multicast failure on OSX

本文关键字:多播 失败 ASIO Boost 上的 OSX      更新时间:2023-10-16

我有一个为Windows和OSX编写的应用程序,它使用Boost ASIO进行网络连接。该应用程序的一部分发送多播消息,供嵌入式设备响应:

std::string ip_addr = "224.0.0.177";
boost::asio::ip::udp::endpoint senderEndpoint(boost::asio::ip::address::from_string(ip_addr), 7076);
m_pcDiscoverySocket->send_to(boost::asio::buffer((void*)pGetDeviceInfoMessage->m_pchData, pGetDeviceInfoMessage->m_ulDataSize), senderEndpoint);

这段代码在Windows上运行得非常好。它在OSX上也能很好地工作,但只有当网络上有DHCP服务器时。当网络上没有DHCP服务器,并且所有内容都有自动ip分配的地址169.254.x.x时,send_to函数会抛出异常,并显示错误消息"send_to:network is reachable"。如果我将上面代码中的IP地址更改为169.254.0.1,那么它运行时没有错误消息,但嵌入式设备显然没有响应,因为它不是广播IP地址。

我有点困惑。有人能解释为什么它会抛出这个错误,或者为什么相同的代码在Windows中工作(在Mac上的VM中运行,硬件相同)吗?

因此,经过大量徒劳的搜索和一些实验,我认为我找到了一个解决方案,将问题中的最后一行代码更改为:

boost::asio::ip::tcp::resolver resolver(m_IOservice);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::host_name(),"");
boost::asio::ip::tcp::resolver::iterator it = resolver.resolve(query);
boost::asio::ip::address interface_ip_address;
while(it!=boost::asio::ip::tcp::resolver::iterator())
{
    interface_ip_address = (it++)->endpoint().address();
    if(interface_ip_address.is_v4())
    {
        m_pcDiscoverySocket->set_option(boost::asio::ip::multicast::outbound_interface(interface_ip_address.to_v4()));
        m_pcDiscoverySocket->send_to(boost::asio::buffer((void*)pGetDeviceInfoMessage->m_pchData, pGetDeviceInfoMessage->m_ulDataSize), senderEndpoint);
        break;
    }
}

基本上,在OSX上,你似乎必须告诉套接字要使用哪个接口,但前提是它没有通过DHCP获得IP地址。这似乎也适用于Windows(尽管以前也适用)。

如果有比我聪明的人能解释为什么这是有效的,以及为什么你必须在OSX上这样做,那么我会把答案归功于他们。