c 获取域名ip exe
- 行业动态
- 2025-02-20
- 3
getaddrinfo
函数解析域名并打印对应的IP地址。
在C语言中,获取域名对应的IP地址是一个常见的网络编程任务,这通常涉及到使用系统调用或库函数来查询DNS(域名系统)并解析域名为IP地址,下面将详细介绍如何使用C语言实现这一功能,包括使用getaddrinfo
函数的示例代码、处理结果以及释放资源的方法。

使用getaddrinfo
函数获取域名IP
包含必要的头文件
要使用getaddrinfo
函数,需要包含以下头文件:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <unistd.h>
准备`addrinfo`结构体
在调用getaddrinfo
之前,需要准备一个addrinfo
结构体来指定所需的地址信息类型,支持IPv4和IPv6,使用TCP连接:

struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // 允许IPv4或IPv6 hints.ai_socktype = SOCK_STREAM; // TCP流 hints.ai_flags = 0; hints.ai_protocol = 0; // 任意协议
调用`getaddrinfo`函数
使用准备好的hints
结构体作为参数,调用getaddrinfo
函数来解析域名:
int status = getaddrinfo("www.example.com", NULL, &hints, &res); if (status != 0) { fprintf(stderr, "getaddrinfo error: %s ", gai_strerror(status)); return 1; }
处理结果
getaddrinfo
函数返回一个链表,其中包含所有匹配的地址信息,遍历这个链表,提取并打印IP地址:
char ipstr[INET6_ADDRSTRLEN]; for (struct addrinfo *p = res; p != NULL; p = p->ai_next) { void *addr; char *ipver; if (p->ai_family == AF_INET) { // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; addr = &(ipv4->sin_addr); ipver = "IPv4"; } else { // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; addr = &(ipv6->sin6_addr); ipver = "IPv6"; } inet_ntop(p->ai_family, addr, ipstr, sizeof(ipstr)); printf(" %s: %s ", ipver, ipstr); }
释放资源
处理完addrinfo
链表后,记得释放它以避免内存泄漏:

freeaddrinfo(res);
完整示例代码
以下是一个完整的示例代码,展示了如何使用getaddrinfo
函数获取域名的IP地址:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <unistd.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <hostname> ", argv[0]); return 1; } const char *hostname = argv[1]; struct addrinfo hints, *result, *p; int ret; char ipstr[INET6_ADDRSTRLEN]; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // 支持IPv4和IPv6 hints.ai_socktype = SOCK_STREAM; // TCP连接 ret = getaddrinfo(hostname, NULL, &hints, &result); if (ret != 0) { fprintf(stderr, "getaddrinfo: %s ", gai_strerror(ret)); return 1; } for (p = result; p != NULL; p = p->ai_next) { void *addr; char *ipver; if (p->ai_family == AF_INET) { // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; addr = &(ipv4->sin_addr); ipver = "IPv4"; } else { // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; addr = &(ipv6->sin6_addr); ipver = "IPv6"; } inet_ntop(p->ai_family, addr, ipstr, sizeof(ipstr)); printf(" %s: %s ", ipver, ipstr); } freeaddrinfo(result); return 0; }
编译并运行上述代码,你将能够看到指定域名的所有IP地址(包括IPv4和IPv6)。
FAQs
Q1: 如果域名没有对应的IP地址怎么办?
A1: 如果域名没有对应的IP地址(例如域名不存在或DNS服务器无法解析),getaddrinfo
函数将返回一个非零的错误码,你应该检查该错误码,并根据需要进行错误处理,可以提示用户检查域名是否正确,或者稍后再试。
Q2: 如何处理IPv6地址?
A2:getaddrinfo
函数同时支持IPv4和IPv6地址,在处理结果时,通过检查p->ai_family
字段来确定地址类型,如果是AF_INET
,则表示是IPv4地址;如果是AF_INET6
,则表示是IPv6地址,然后使用相应的结构体(sockaddr_in
或sockaddr_in6
)来提取地址,并使用inet_ntop
函数将其转换为字符串形式。