我有一个虚拟机,我想从 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 地址?
在使用其结果之前,您没有检查
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()
或等价物。