我正在尝试在OSX上打开IPv6多播侦听端口,但在尝试运行“join_group”选项时收到错误代码49。以下是导致probem的代码示例:
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上发生此错误?
答案 0 :(得分:0)
在某些情况下,操作系统无法确定用于自动加入群组的界面。 您可以手动设置接口索引(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;
}