在Linux系统上用C++将主机名称转换为IPv4、IPv6地址

在Linux系统上用C++将主机名称转换为IPv4、IPv6地址

功能

指定一个std::string类型的主机名称,函数解析主机名称为IP地址,含IPv4和IPv6,解析结果以std::vector类型返回。解析出错或者解析失败抛出std::string类型的异常消息。

源代码 

以前随便写的一个解析域名为IP地址的功能现在需要支持IPv6,所以做了些调整。最后结果如下:

/*

C++,将域名解析为IP地址(含IPv4和IPv6)
编译: g++ -o main main.cpp
执行:./main
效果:

$ ./main 
13.226.120.15
13.226.120.23
13.226.120.56
13.226.120.3
2600:9000:21e1:1200:1c:b3b0:7700:93a1
2600:9000:21e1:bc00:1c:b3b0:7700:93a1
2600:9000:21e1:9a00:1c:b3b0:7700:93a1
2600:9000:21e1:4e00:1c:b3b0:7700:93a1
2600:9000:21e1:a200:1c:b3b0:7700:93a1
2600:9000:21e1:3600:1c:b3b0:7700:93a1
2600:9000:21e1:1a00:1c:b3b0:7700:93a1
2600:9000:21e1:1800:1c:b3b0:7700:93a1

*/

// getaddrinfo, gai_strerror, freeaddrinfo
#include 
#include 
#include 

// inet_ntop
#include 

// strerror
#include 

#include 
#include 
#include 

// 域名解析为IP地址,返回地址列表。
std::vector hostToIPs(const std::string& host) {
    std::vector addressList;

    addrinfo hints;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;
    hints.ai_flags = 0;
    hints.ai_canonname = nullptr;
    hints.ai_addr = nullptr;
    hints.ai_next = nullptr;

    addrinfo* result = nullptr;

    auto res = getaddrinfo(host.c_str(), nullptr, &hints, &result);
    if (0 != res) {
        throw std::string(gai_strerror(res));
    }

    if (nullptr != result) {
        int bufferSize = 64;
        char buffer[64];
        void* pointer;

        for (auto rp = result; rp != nullptr; rp = rp->ai_next) {
            switch (rp->ai_family) {
            case AF_INET:
                pointer = (void*)&(((sockaddr_in*)(rp->ai_addr))->sin_addr);
                break;
            case AF_INET6:
                pointer = (void*)&(((sockaddr_in6*)(rp->ai_addr))->sin6_addr);
                break;
            default:
                continue;
            }
            if (nullptr == inet_ntop(rp->ai_family, pointer, buffer, bufferSize)) {
                freeaddrinfo(result);
                throw std::string("Run inet_ntop fail, errno is ") + std::to_string(errno)
                    + ", message: " + std::string(strerror(errno));
            }
            addressList.emplace_back(std::string(buffer));
        }
        freeaddrinfo(result);
    }

    if (addressList.size() <= 0) {
        throw std::string("address list is empty");
    }
    return addressList;
}

int main() {
    try {
        for (const auto& address : hostToIPs("www.english.com")) {
            std::cout << address << std::endl;
        }
    } catch (const std::string& e) {
        std::cout << e << std::endl;
    }
    return 0;
}

运行截图

程序在Ubuntu上开发调试,结果是OK的。解析结果支持IPv4和IPv6地址,主要参考材料是man手册。运行截图:

在Linux系统上用C++将主机名称转换为IPv4、IPv6地址_第1张图片

你可能感兴趣的:(IT技术相关,linux,c++,网络)