将结构体sockaddr_in6*转换为boost::asio::ip::address_v6



我正在为TCP/ip客户端/服务器程序实现一个主机名/ip地址解析器。我可以成功地将IPv4地址从sockaddr_in*转换为boost::asio::ip::address_v4,但我无法获得从struct sockaddr_in6*boost::asio::ip::address_v6的IPv6转换权限:

#include <iostream>
using std::cout;
#include <netdb.h>
#include <stdexcept>
using std::domain_error;
#include <sys/socket.h>
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <boost/asio.hpp>
using boost::asio::ip::address;
using boost::asio::ip::address_v4;
using boost::asio::ip::address_v6;
vector<address> getAddresses(string const &hostname)
{
struct addrinfo req = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
struct addrinfo *pai;
int error = getaddrinfo(hostname.c_str(), nullptr, &req, &pai);
if (error)
throw domain_error("Could not resolve host name.");
vector<address> addresses;
for(struct addrinfo *info = pai; info != nullptr; info = info->ai_next) {
if (info->ai_family == AF_INET) {
auto ipv4socket = reinterpret_cast<struct sockaddr_in*>(info->ai_addr);
auto ipv4addr = address_v4(htonl(ipv4socket->sin_addr.s_addr));
addresses.emplace_back(ipv4addr);
}
/*
* TODO: Implement IPv6 support.
else {
auto ipv6socket = reinterpret_cast<struct sockaddr_in6*>(info->ai_addr);
auto ipv6base = reinterpret_cast<array<unsigned char, 16>>(ipv6socket->sin6_addr.__in6_u);
auto ipv6addr = address_v6(ipv6base, ipv6socket->sin6_scope_id);
addresses.emplace_back(ipv6addr);
}
*/
}
return addresses;
}
int main()
{
auto addresses = getAddresses("www.google.de");
for (auto ipa : addresses)
cout << "Address: " << ipa << "n";
return 0;
}

开始工作:

vector<address> getAddresses(string const &hostname)
{
struct addrinfo req = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
struct addrinfo *pai;
int error = getaddrinfo(hostname.c_str(), nullptr, &req, &pai);
if (error)
throw domain_error("Could not resolve host name.");
vector<address> addresses;
for(struct addrinfo *info = pai; info != nullptr; info = info->ai_next) {
if (info->ai_family == AF_INET) {
auto ipv4socket = reinterpret_cast<struct sockaddr_in*>(info->ai_addr);
auto ipv4addr = address_v4(htonl(ipv4socket->sin_addr.s_addr));
addresses.emplace_back(ipv4addr);
} else {
auto ipv6socket = reinterpret_cast<struct sockaddr_in6*>(info->ai_addr);
array<unsigned char, 16> bytes = {
ipv6socket->sin6_addr.s6_addr[0],
ipv6socket->sin6_addr.s6_addr[1],
ipv6socket->sin6_addr.s6_addr[2],
ipv6socket->sin6_addr.s6_addr[3],
ipv6socket->sin6_addr.s6_addr[4],
ipv6socket->sin6_addr.s6_addr[5],
ipv6socket->sin6_addr.s6_addr[6],
ipv6socket->sin6_addr.s6_addr[7],
ipv6socket->sin6_addr.s6_addr[8],
ipv6socket->sin6_addr.s6_addr[9],
ipv6socket->sin6_addr.s6_addr[10],
ipv6socket->sin6_addr.s6_addr[11],
ipv6socket->sin6_addr.s6_addr[12],
ipv6socket->sin6_addr.s6_addr[13],
ipv6socket->sin6_addr.s6_addr[14],
ipv6socket->sin6_addr.s6_addr[15]
};
auto ipv6addr = address_v6(bytes, ipv6socket->sin6_scope_id);
addresses.emplace_back(ipv6addr);
}
}
return addresses;
}

下一站:代码审查

最新更新