【问题标题】:Boost ASIO IPv6 join_group does not work on OS XBoost ASIO IPv6 join_group 在 OS X 上不起作用
【发布时间】:2014-06-01 04:11:15
【问题描述】:

我尝试在 OSX 上打开 IPv6 多播侦听端口,但在尝试运行“join_group”选项时收到错误代码 49。以下是导致问题的代码示例:

ip6_listen=boost::make_shared<boost::asio::ip::udp::socket>(io_service);
ip6_listen->open(boost::asio::ip::udp::v6());
ip6_listen->set_option(boost::asio::ip::udp::socket::reuse_address(true));
ip6_listen->bind(boost::asio::ip::udp::endpoint(boost::asio::ip::address_v6::any(),ANNOUNCE_PORT));
ip6_listen->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address_v6::from_string("FF01::AC22"))); //Throws error "49"

目前尚不清楚为什么会引发错误,因为它在 Windows 和 Linux 上都能正常工作。为什么这个错误只发生在 OSX 上?

【问题讨论】:

  • 错误 49 是“无法分配请求的地址”;您是否在 OSX 系统上尝试过其他地址(或其他简单的网络连接代码)以确保它不是其他可能的问题,或者您没有绑定到该套接字地址/端口的其他东西?
  • 绑定工作正常。最后一行“join_group”不起作用。是的,我尝试过其他多播地址。

标签: c++ macos sockets boost boost-asio


【解决方案1】:

在某些情况下,操作系统无法确定用于自动加入群组的接口。 您可以手动设置接口索引(documentation):

ip6_listen->set_option(boost::asio::ip::multicast::outbound_interface(0);

至于如何获取接口索引,可以使用这段代码:

#include <arpa/inet.h>
#include <ifaddrs.h>
#include <iostream>
#include <map>
#include <net/if.h>
#include <sys/types.h>

std::vector<uint32_t> get_v6_ifindices {
    std::vector<uint32_t> res;
    ifaddrs *ifs;
    if (getifaddrs(&ifs)) {
        std::cerr << "Error enumerating interfaces: " << errno << '\n';
        return res;
    }
    for (auto addr = ifs; addr != nullptr; addr = addr->ifa_next) {
        // No address? Skip.
        if (addr->ifa_addr == nullptr) continue;
        // Interface doesn't support multicast? Skip.
        if (!(addr->ifa_flags & IFF_MULTICAST)) continue;
        // Interface isn't active? Skip.
        if (!(addr->ifa_flags & IFF_UP)) continue;

        uint32_t idx = if_nametoindex(addr->ifa_name);
        ifaces[idx].name = addr->

        switch (addr->ifa_addr->sa_family) {
        case AF_INET: auto v4addr = ntohl(((sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr); break;
        case AF_INET6: {
            res.push_back(idx);
            auto sa_in6 = (sockaddr_in6 *)addr->ifa_addr;
            auto v6addr = (const unsigned char *)&sa_in6->sin6_addr;
        }
#ifdef __APPLE__
        case AF_CCITT: break;
        case AF_LINK: break;
#else
        case AF_PACKET: break;
#endif
        default: std::clog << "Unknown interface type " << static_cast<int>(addr->ifa_addr->sa_family) << '\n';
        }
    }
    freeifaddrs(ifs);
    return res;
}

【讨论】:

    猜你喜欢
    • 2012-01-30
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 2015-06-15
    • 2021-01-14
    • 1970-01-01
    相关资源
    最近更新 更多