Chinaunix首页 | 论坛 | 博客
  • 博客访问: 316607
  • 博文数量: 90
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 113
  • 用 户 组: 普通用户
  • 注册时间: 2016-01-27 19:56
文章分类

全部博文(90)

文章存档

2017年(12)

2016年(78)

分类: 嵌入式

2016-03-10 14:53:04

addrinfo结构体的定义如下:

  1. struct addrinfo {
  2.      int ai_flags; /* customize behavior */
  3.      int ai_family; /* address family */
  4.      int ai_socktype; /* socket type */
  5.      int ai_protocol; /* protocol */
  6.      socklen_t ai_addrlen; /* length in bytes of address */
  7.      struct sockaddr *ai_addr; /* address */
  8.      char *ai_canonname; /* canonical name of host */
  9.      struct addrinfo *ai_next; /* next in list */
  10.      .
  11.      .
  12.      .
  13.    };
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指定了如何来处理地址和名字,可取值如下:

QQ截图20120409193145

getaddrinfo函数 定义及需要的头文件如下:

  1. #include <sys/socket.h>
  2. #include <netdb.h>

  3. int getaddrinfo(const char *restrict host,
  4.                 const char *restrict service,
  5.                 const struct addrinfo *restrict hint,
  6.                 struct addrinfo **restrict res);




  7. Returns: 0 if OK, nonzero error code on error


  8. void freeaddrinfo(struct addrinfo *ai);
getaddrinfo函数允许将一个主机名字和服务名字映射到一个地址。
使用示例如下:
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include <netdb.h>
  4. #include <arpa/inet.h>

  5. void
  6. print_family(struct addrinfo *aip)
  7. {
  8.     printf(" family ");
  9.     switch (aip->ai_family) {
  10.     case AF_INET:
  11.         printf("inet");
  12.         break;
  13.     case AF_INET6:
  14.         printf("inet6");
  15.         break;
  16.     case AF_UNIX:
  17.         printf("unix");
  18.         break;
  19.     case AF_UNSPEC:
  20.         printf("unspecified");
  21.         break;
  22.     default:
  23.         printf("unknown");
  24.     }
  25. }

  26. void
  27. print_type(struct addrinfo *aip)
  28. {
  29.     printf(" type ");
  30.     switch (aip->ai_socktype) {
  31.     case SOCK_STREAM:
  32.         printf("stream");
  33.         break;
  34.     case SOCK_DGRAM:
  35.         printf("datagram");
  36.         break;
  37.     case SOCK_SEQPACKET:
  38.         printf("seqpacket");
  39.         break;
  40.     case SOCK_RAW:
  41.         printf("raw");
  42.         break;
  43.     default:
  44.         printf("unknown (%d)", aip->ai_socktype);
  45.     }
  46. }

  47. void
  48. print_protocol(struct addrinfo *aip)
  49. {
  50.     printf(" protocol ");
  51.     switch (aip->ai_protocol) {
  52.     case 0:
  53.         printf("default");
  54.         break;
  55.     case IPPROTO_TCP:
  56.         printf("TCP");
  57.         break;
  58.     case IPPROTO_UDP:
  59.         printf("UDP");
  60.         break;
  61.     case IPPROTO_RAW:
  62.         printf("raw");
  63.         break;
  64.     default:
  65.         printf("unknown (%d)", aip->ai_protocol);
  66.     }
  67. }

  68. void
  69. print_flags(struct addrinfo *aip)
  70. {
  71.     printf("flags");
  72.     if (aip->ai_flags == 0) {
  73.         printf(" 0");
  74.     } else {
  75.         if (aip->ai_flags & AI_PASSIVE)
  76.             printf(" passive");
  77.         if (aip->ai_flags & AI_CANONNAME)
  78.             printf(" canon");
  79.         if (aip->ai_flags & AI_NUMERICHOST)
  80.             printf(" numhost");
  81. #if defined(AI_NUMERICSERV)
  82.         if (aip->ai_flags & AI_NUMERICSERV)
  83.             printf(" numserv");
  84. #endif
  85. #if defined(AI_V4MAPPED)
  86.         if (aip->ai_flags & AI_V4MAPPED)
  87.             printf(" v4mapped");
  88. #endif
  89. #if defined(AI_ALL)
  90.         if (aip->ai_flags & AI_ALL)
  91.             printf(" all");
  92. #endif
  93.     }
  94. }

  95. int
  96. main(int argc, char *argv[])
  97. {
  98.     struct addrinfo        *ailist, *aip;
  99.     struct addrinfo        hint;
  100.     struct sockaddr_in    *sinp;
  101.     const char             *addr;
  102.     int                 err;
  103.     char                 abuf[INET_ADDRSTRLEN];

  104.     if (argc != 3)
  105.         printf("usage: %s nodename service", argv[0]);
  106.     hint.ai_flags = AI_CANONNAME;
  107.     hint.ai_family = 0;
  108.     hint.ai_socktype = 0;
  109.     hint.ai_protocol = 0;
  110.     hint.ai_addrlen = 0;
  111.     hint.ai_canonname = NULL;
  112.     hint.ai_addr = NULL;
  113.     hint.ai_next = NULL;
  114.     if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0)
  115.         printf("getaddrinfo error: %s", gai_strerror(err));
  116.     for (aip = ailist; aip != NULL; aip = aip->ai_next) {
  117.         print_flags(aip);
  118.         print_family(aip);
  119.         print_type(aip);
  120.         print_protocol(aip);
  121.         printf("\n\thost %s", aip->ai_canonname?aip->ai_canonname:"-");
  122.         if (aip->ai_family == AF_INET) {
  123.             sinp = (struct sockaddr_in *)aip->ai_addr;
  124.             addr = inet_ntop(AF_INET, &sinp->sin_addr, abuf,INET_ADDRSTRLEN);
  125.             printf(" address %s", addr?addr:"unknown");
  126.             printf(" port %d", ntohs(sinp->sin_port));
  127.         }
  128.         printf("\n");
  129.     }
  130.     exit(0);
  131. }
代码说明:sinp = (struct sockaddr_in *)aip->ai_addr;会将struct sockaddr 变量强制转化为struct sockaddr_in 类型
inet_ntop函数用于在二进制格式与点分十进制格式表示(a.b.c.d)之间进行转换
执行结果:#./a X86-PC nfs
  1. root@X86-PC:/home/cheney/work-link/linux_C_Test/linux-program/fig16# ./a X86-PC nfs
  2. flags canon family inet type stream protocol TCP
  3. host X86-PC address 127.0.1.1 port 2049
  4. flags canon family inet type datagram protocol UDP
  5. host - address 127.0.1.1 port 2049
  6. root@X86-PC:/home/cheney/work-link/linux_C_Test/linux-program/fig16#
阅读(1615) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~