原文链接:
http://blog.chinaunix.net/uid-26583794-id-3167485.html
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#
阅读(727) | 评论(0) | 转发(0) |