如何从 C++ 代码获取 vm 的 IPv6 地址?

问题描述 投票:0回答:1

我有一个虚拟机,我想从 C++ 代码中获取 IPv6 地址。 我找到了 getaddrinfo 函数,但我不明白使用什么参数来获取 IPv6 地址。 我试过了

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

using namespace std;

int main() {
    addrinfo hint, *res = NULL, *p = NULL;
    int err;
    memset(&hint, 0, sizeof hint);
    hint.ai_family = AF_UNSPEC;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_flags = AI_ADDRCONFIG;
    err = getaddrinfo(NULL, "http", &hint, &res);

    std::cout << res->ai_canonname;

    return 0;
}

但是得到

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
错误。如何从 C++ 代码获取 vm 的 IPv6 地址?

c++ ubuntu ipv6
1个回答
1
投票

在使用其结果之前,您没有检查

getaddrinfo()
是否成功。

此外,

res->ai_canonname
不包含您要查找的IP地址。它存储在
res->ai_addr
中。但是,它以二进制形式存储(作为
sockaddr_in6
结构)。要获得文本形式,您可以将二进制 IP 传递给
getnameinfo()
inet_ntop()
或其他等效函数。

此外,

getaddrinfo()
返回一个 IP 链表。一台机器可以安装多个 IP,因此您应该遍历整个列表,打印出每个可用的 IP。

尝试更像这样的东西:

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

using namespace std;

int main() {
    addrinfo hint = {}, *res;

    hint.ai_family = AF_INET6;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_flags = AI_ADDRCONFIG;

    int err = getaddrinfo(NULL, "http", &hint, &res);
    if (err != 0) {
        std::cerr << "getaddrinfo failed, error " << err << '\n';
    }
    else {
        char ip[NI_MAXHOST];
        for (addrinfo *p = res; p != NULL; p = p->ai_next) {
            if (getnameinfo(res->ai_addr, res->ai_addrlen, ip, sizeof(ip), NULL, 0, NI_NUMERICHOST) != 0) continue;
            /* alternatively:
            inet_ntop(AF_INET6, &(reinterpret_cast<sockaddr_in6*>(res->ai_addr)->sin6_addr), ip, sizeof(ip);
            */
            std::cout << ip << '\n';
        }
        freeaddrinfo(res);
    }

    return 0;
}

然而,话虽如此,

getaddrinfo()
并不是获取本地 IP 的最佳选择。如果您的平台支持它,您应该使用
getifaddrs()
或等价物。

© www.soinside.com 2019 - 2024. All rights reserved.