使用getaddrinfo进行DNS解析
先上代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
int main()
{
int ret, fd;
char addrstr[] = "www.baidu.com";
char portstr[] = "443";
struct addrinfo* remote;
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_PASSIVE,
};
ret = getaddrinfo(addrstr, portstr, &hints, &remote);
if (ret != 0)
{
perror("getaddrinfo");
return -1;
}
printf("%s\n", inet_ntoa(((struct sockaddr_in*)(remote->ai_addr))->sin_addr));
if ((fd = socket(remote->ai_addr->sa_family, SOCK_STREAM, 0)) == -1)
{
perror("socket");
return -1;
}
if ((ret == connect(fd, remote->ai_addr, remote->ai_addrlen)) == -1)
{
perror("connect");
return -1;
}
freeaddrinfo(remote);
return 0;
}
运行结果为DNS解析出的百度IP地址。
test@test:~/my$ ./a.out
180.101.49.12
getaddrinfo调用成功返回0,失败返回错误码,错误码可由gai_strerror(int errcode)转为含义字串。调用成功结果输出在第四个参数中,也就是代码中的&remote。
函数定义及结构体struct addrinfo如下:
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
const char *gai_strerror(int errcode);
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
remote->ai_addr为struct sockaddr结构,可直接被套接字接口调用。