使用getaddrinfo解析DNS域名

函数原型

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;
}

你可能感兴趣的:(使用getaddrinfo解析DNS域名)