c语言如何使用getaddrinfo函数
时间: 2024-09-06 17:07:37 浏览: 66
get_address_info.zip_dns _getaddrinfo
`getaddrinfo` 是一个用于网络服务查找的函数,它可以在 IPv4 和 IPv6 地址之间透明地工作,支持地址信息查询和协议的自动选择。该函数在 C 语言中用于根据主机名或地址以及服务名或端口号获取地址信息结构体列表。
下面是使用 `getaddrinfo` 的基本步骤:
1. 填充一个 `addrinfo` 结构体,用于指定查询的类型(例如,是否希望获得 IPv4 地址或 IPv6 地址)。
2. 调用 `getaddrinfo` 函数,传入主机名、服务名(或端口号)、`addrinfo` 结构体以及一个用于接收地址信息结构体列表的指针。
3. 遍历由 `getaddrinfo` 返回的地址信息结构体链表,并处理每个元素。
4. 使用完地址信息后,释放这些结构体。
示例代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main() {
const char *hostname = "www.example.com";
const char *service = "http";
struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];
// 准备 hints 结构体
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // AF_INET 或 AF_INET6,以获取 IPv4 或 IPv6
hints.ai_socktype = SOCK_STREAM; // TCP 流式套接字
hints.ai_flags = AI_PASSIVE; // 告诉系统该套接字用于监听
// 调用 getaddrinfo
if ((status = getaddrinfo(hostname, service, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
// 遍历返回的地址信息链表
for (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";
}
// 转换 IP 地址为文本形式
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf("Address information for %s service:\n", service);
printf("Protocol: %s\n", p->ai_protocol == IPPROTO_TCP ? "TCP" : "UDP");
printf("Address: %s\n", ipstr);
printf("Port: %u\n", ntohs(((struct sockaddr_in *)p->ai_addr)->sin_port));
}
// 释放地址信息链表
freeaddrinfo(res);
return 0;
}
```
请注意,使用 `getaddrinfo` 时,需要包含 `<netdb.h>` 头文件,并链接标准 C 库。
阅读全文