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;/* lengthin bytes of address*/
- struct sockaddr *ai_addr;/* address*/
- char *ai_canonname;/* canonical name of host*/
- struct addrinfo *ai_next;/*nextin list*/
- .
- .
- .
- };
- ai_family指定了地址族,可取值如下:
- AF_INET 2 IPv4
- AF_INET6 23 IPv6
- AF_UNSPEC 0 协议无关
ai_socktype指定我套接字的类型
SOCK_STREAM 1 流
SOCK_DGRAM 2 数据报
在AF_INET通信域中套接字类型SOCK_STREAM的默认协议是TCP(传输控制协议)
在AF_INET通信域中套接字类型SOCK_DGRAM的默认协议是UDP(用户数据报协议)
ai_protocol指定协议类型。可取的值取决于ai_address和ai_socktype的值
ai_flags指定了如何来处理地址和名字,可取值如下:
getaddrinfo函数 定义及需要的头文件如下:
- #include <sys/socket.h>
- #include <netdb.h>
- int getaddrinfo(const char*restrict host,
- const char*restrict service,
- const struct addrinfo*restrict hint,
- struct addrinfo **restrict res);
- Returns: 0if OK, nonzeroerror codeonerror
- void freeaddrinfo(struct addrinfo*ai);
getaddrinfo函数允许将一个主机名字和服务名字映射到一个地址。
使用示例如下:
- #include<stdio.h>
- #include<stdlib.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- void
- print_family(struct addrinfo*aip)
- {
- printf(" family ");
- switch (aip->ai_family){
- case AF_INET:
- printf("inet");
- break;
- case AF_INET6:
- printf("inet6");
- break;
- case AF_UNIX:
- printf("unix");
- break;
- case AF_UNSPEC:
- printf("unspecified");
- break;
- default:
- printf("unknown");
- }
- }
- void
- print_type(struct addrinfo*aip)
- {
- printf(" type ");
- switch (aip->ai_socktype){
- case SOCK_STREAM:
- printf("stream");
- break;
- case SOCK_DGRAM:
- printf("datagram");
- break;
- case SOCK_SEQPACKET:
- printf("seqpacket");
- break;
- case SOCK_RAW:
- printf("raw");
- break;
- default:
- printf("unknown (%d)", aip->ai_socktype);
- }
- }
- void
- print_protocol(struct addrinfo*aip)
- {
- printf(" protocol ");
- switch (aip->ai_protocol){
- case 0:
- printf("default");
- break;
- case IPPROTO_TCP:
- printf("TCP");
- break;
- case IPPROTO_UDP:
- printf("UDP");
- break;
- case IPPROTO_RAW:
- printf("raw");
- break;
- default:
- printf("unknown (%d)", aip->ai_protocol);
- }
- }
- void
- print_flags(struct addrinfo*aip)
- {
- printf("flags");
- if(aip->ai_flags== 0){
- printf(" 0");
- }else{
- if(aip->ai_flags& AI_PASSIVE)
- printf(" passive");
- if(aip->ai_flags& AI_CANONNAME)
- printf(" canon");
- if(aip->ai_flags& AI_NUMERICHOST)
- printf(" numhost");
- #if defined(AI_NUMERICSERV)
- if(aip->ai_flags& AI_NUMERICSERV)
- printf(" numserv");
- #endif
- #if defined(AI_V4MAPPED)
- if(aip->ai_flags& AI_V4MAPPED)
- printf(" v4mapped");
- #endif
- #if defined(AI_ALL)
- if(aip->ai_flags& AI_ALL)
- printf(" all");
- #endif
- }
- }
- int
- main(int argc, char*argv[])
- {
- struct addrinfo *ailist,*aip;
- struct addrinfo hint;
- struct sockaddr_in *sinp;
- const char *addr;
- int err;
- char abuf[INET_ADDRSTRLEN];
- if(argc!= 3)
- printf("usage: %s nodename service", argv[0]);
- hint.ai_flags= AI_CANONNAME;
- hint.ai_family= 0;
- hint.ai_socktype= 0;
- hint.ai_protocol= 0;
- hint.ai_addrlen= 0;
- hint.ai_canonname=NULL;
- hint.ai_addr=NULL;
- hint.ai_next=NULL;
- if((err= getaddrinfo(argv[1], argv[2],&hint,&ailist))!= 0)
- printf("getaddrinfo error: %s", gai_strerror(err));
- for(aip= ailist; aip!=NULL; aip= aip->ai_next){
- print_flags(aip);
- print_family(aip);
- print_type(aip);
- print_protocol(aip);
- printf("\n\thost %s", aip->ai_canonname?aip->ai_canonname:"-");
- if(aip->ai_family== AF_INET){
- sinp =(struct sockaddr_in*)aip->ai_addr;
- addr = inet_ntop(AF_INET,&sinp->sin_addr, abuf,INET_ADDRSTRLEN);
- printf(" address %s", addr?addr:"unknown");
- printf(" port %d", ntohs(sinp->sin_port));
- }
- printf("\n");
- }
- exit(0);
- }
代码说明:sinp = (struct sockaddr_in *)aip->ai_addr;会将struct sockaddr 变量强制转化为struct sockaddr_in 类型
inet_ntop函数用于在二进制格式与点分十进制格式表示(a.b.c.d)之间进行转换
执行结果:#./a X86-PC nfs
- root@X86-PC:/home/cheney/work-link/linux_C_Test/linux-program/fig16# ./a X86-PC nfs
- flags canon family inet type stream protocol TCP
- host X86-PC address 127.0.1.1 port 2049
- flags canon family inet type datagram protocol UDP
- host - address 127.0.1.1 port 2049
- root@X86-PC:/home/cheney/work-link/linux_C_Test/linux-program/fig16#