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 */
- .
- .
- .
- };
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: 0 if OK, nonzero error code on error
- 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#
阅读(1839) | 评论(0) | 转发(0) |