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

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

功能

指定一个std::string类型的主机名称,函数解析主机名称为IP地址,含IPv4和IPv6,解析结果以std::vector<std::string>类型返回。解析出错或者解析失败抛出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 <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

// inet_ntop
#include <arpa/inet.h>

// strerror
#include <cstring>

#include <string>
#include <vector>
#include <iostream>

// 域名解析为IP地址,返回地址列表。
std::vector<std::string> hostToIPs(const std::string& host) {
    std::vector<std::string> 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手册。运行截图:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值