函数原型
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );
-
hostname:要查询的主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)
-
service:服务名可以是十进制的端口号,也可以是已定义的服务名称,如ftp、http等
-
hints:可以是一个空指针,也可以是一个指向某个addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:如果指定的服务既支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口的信息
-
result:本函数通过result指针参数返回一个指向addrinfo结构体链表的指针。
-
struct addrinfo
struct addrinfo {
int ai_flags; /* customize behavior */
int ai_family; /* address family */
int ai_socktype; /* socket type */
int ai_protocol; /* protocol */
socklen_t ai_addrlen; /* length in bytes of address */
struct sockaddr *ai_addr; /* address */
char *ai_canonname; /* canonical name of host */
struct addrinfo *ai_next; /* next in list */
};
返回值:0——成功,非0——出错
ai_family 可以取值AF_INET 、 AF_INET6, AF_UNSPEC。AF_INET获取ipv4地址,AF_INET6获取ipv6地址,AF_UNSPEC混用
ai_socktype 此字段指定首选的套接字类型,例如SOCK_STREAM或SOCK_DGRAM。在此字段中指定0表示任何类型的套接字地址都可以由getaddrinfo()返回。
ai_protocol 此字段指定返回的套接字地址的协议。在此字段中指定0表示使用任何协议的套接字地址都可以由getaddrinfo()返回。
代码示例
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<resolv.h>
int main()
{
char* hostname = "www.zju.edu.cn";
char ipbuf[16],ip6buf[64];
struct addrinfo hints,*res,*rp;
struct sockaddr_in *addr;
struct sockaddr_in6 *addr6;
int err;
memset(&hints,0,sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
err = getaddrinfo(hostname,NULL,&hints,&res);
if(err)
{
printf("error %d: %s\n",err,gai_strerror(err));
return 1;
}
for(rp = res;rp != NULL;rp = rp->ai_next)
{
if(rp->ai_family == AF_INET)
{ addr = (struct sockaddr_in*)rp->ai_addr;
printf("%s\n",inet_ntop(AF_INET,&addr->sin_addr,ipbuf,16));
}
else
{ addr6 = (struct sockaddr_in6*)rp->ai_addr;
printf("%s\n",inet_ntop(AF_INET6,&addr6->sin6_addr,ip6buf,64));
}
}
freeaddrinfo(res);
return 0;
}