windows10 c++获取本机IPv4,ipv6,查询本机Ipv4,ipv6
阅读原文时间:2023年07月11日阅读:2

演示环境: win10+VS2017

需要下面的库支持:

ws2_32.lib

需要下面的,添加到项目属性-> c/c++ -> 预处理器定义

_WINSOCK_DEPRECATED_NO_WARNINGS


int net_adapter_helper::get_ipv4_win(std::list<std::string>& out_list_ip4)
{
    int error_id = 0;
    WORD sock_ver;
    WSADATA wsaData;
    int ret_val = 0;
    sock_ver            = MAKEWORD(2, 2);
    ret_val                = WSAStartup(sock_ver, &wsaData);
    if (0                != ret_val)
    {
        error_id = GetLastError();
        return error_id;
    }

    if (    2   != LOBYTE(wsaData.wVersion)   ||
            2    !=HIBYTE(wsaData.wVersion) )
    {
        WSACleanup();
        error_id = GetLastError();
        return error_id;
    }

// -------------------------------------------------------------------------------

    const int len_256        = 256;
    char name_host[len_256] = { 0 };

    gethostname(name_host, sizeof(name_host));

    PHOSTENT hostinfo;
    // 1.
    if (NULL == (hostinfo = gethostbyname(name_host)))
    {
        error_id = GetLastError();
        return error_id;
    }

    std::string str_ip4;
    char tmp_name_arr[16] = { 0 };
    while (NULL != *(hostinfo->h_addr_list) )
    {
        inet_ntop(AF_INET, (struct in_addr *) *hostinfo->h_addr_list, tmp_name_arr, 16);
        str_ip4 = std::string(tmp_name_arr);
        out_list_ip4.push_back(str_ip4);

        hostinfo->h_addr_list++;

        memset(tmp_name_arr, 0, 16);
    }

    WSACleanup();

    return error_id;
}


int net_adapter_helper::get_ipv6_win(std::list<std::string>& out_list_ip6)
{

    int error_id = 0;
    WORD sock_ver;
    WSADATA wsaData;
    int ret_val = 0;
    sock_ver = MAKEWORD(2, 2);
    ret_val = WSAStartup(sock_ver, &wsaData);
    if (0 != ret_val)
    {
        error_id = GetLastError();
        return error_id;
    }

    if (2 != LOBYTE(wsaData.wVersion) ||
        2 != HIBYTE(wsaData.wVersion))
    {
        WSACleanup();
        error_id = GetLastError();
        return error_id;
    }

    // -------------------------------------------------------------------------------

    struct addrinfo hint;

    hint.ai_family        = AF_INET6;
    hint.ai_socktype    = SOCK_STREAM;
    hint.ai_flags        = AI_PASSIVE;
    hint.ai_protocol    = 0;
    hint.ai_addrlen        = 0;
    hint.ai_canonname    = NULL;
    hint.ai_addr        = NULL;
    hint.ai_next        = NULL;

    const int len_256            = 256;
    char name_host[len_256]        = { 0 };

    struct addrinfo *pailist    = nullptr;
    struct addrinfo *paip        = nullptr;
    const char port_str[]        = { "10086" };

    ret_val = getaddrinfo(name_host, port_str, &hint, &pailist); 

    // 1.
    if (0 > ret_val || 0 > pailist)
    {
        ret_val = GetLastError();

        WSACleanup();
        return ret_val;
    }

    // 2.
    struct sockaddr_in6 *psinp6 = nullptr;
    for (paip = pailist; NULL != paip; paip = paip->ai_next)
    {
        paip->ai_family = AF_INET6;
        psinp6 = (struct sockaddr_in6 *)paip->ai_addr;
        if (nullptr != psinp6 && NULL != psinp6)
        {
            std::string str_ipv6;
            for (int i = 0; i < 16; i++)
            {
                if (((i - 1) % 2) && (i > 0))
                    str_ipv6 += std::string(":");

                str_ipv6 += str_format("%02X", psinp6->sin6_addr.u.Byte[i]);
            }

            out_list_ip6.push_back(str_ipv6);
        }
    }

    WSACleanup();

    return ret_val;
}


std::list <std::string> ip4_list;
std::list <std::string> ip6_list;

int ret_val = net_adapter_helper::get_instance().get_ipv4_win(ip4_list);
if (0 != ret_val)
{
    cout << "\n\nipv4 error = " << ret_val << endl;
}
else
{
    int index = 0;
    for (auto item : ip4_list)
    {
        cout << "第" << ++index << "个ip4 = " << item.c_str() << endl;
    }
}

cout << "\n\n";

ret_val = net_adapter_helper::get_instance().get_ipv6_win(ip6_list);
if (0 != ret_val)
{
    cout << "\n\nipv6 error = " << ret_val << endl;
}
else
{
    int index = 0;
    for (auto item : ip6_list)
    {
        cout << "第" << ++index << "个ip6 = " << item.c_str() << endl;
    }
}