Chinaunix首页 | 论坛 | 博客
  • 博客访问: 757858
  • 博文数量: 144
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1150
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-17 14:32
个人简介

小公司研发总监,既当司令也当兵!

文章分类

全部博文(144)

分类: LINUX

2015-06-04 23:27:42

在网络中,主机都是用IP地址标示的;但是,出于很多理由,我们应该使用名字,而非纯数字:名字比较好记,数值地址可以变动但名字可以不变(如域名),随着往IPV6上转移,地址变得很长,数值书写容易出错等等。本文示例Linux几个处理名字与地址转换的函数的使用:

点击(此处)折叠或打开

  1. #include <netdb.h>
  2. #include <sys/socket.h>
  3. #include <arpa/inet.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <netinet/in.h>
  7. #include <getopt.h>

  8. struct option g_opts[] = {
  9.     {"host", required_argument, NULL, 'h'},
  10.     {"server", required_argument, NULL, 's'},
  11.     {"protocol", required_argument, NULL, 'p'},
  12.     {"help", no_argument, NULL, 'H'}
  13. };

  14. /* struct hostent
  15.    {
  16.     char *h_name;
  17.     char **h_aliases;
  18.     int h_addrtype;
  19.     int h_length;
  20.     char **h_addr_list;
  21.     #define h_addr h_addr_list[0]
  22.    };
  23.  */

  24. /*
  25. struct servent {
  26.     char *s_name;    //official service name
  27.     char **s_aliases;    //alias list
  28.     int s_port;         //port number, network-byte order
  29.     char *s_proto;        // protocol to use
  30. */
  31. void showUsage()
  32. {
  33.     printf("Usage:\n\tidns -h [ipstr/hostname]\n\t -s [servname/servport] -g [protocol]\n");
  34. }

  35. static void printServent(struct servent *sptr)
  36. {
  37.     char **pptr;

  38.     printf("Server name: %s\n", sptr->s_name);

  39.     pptr = sptr->s_aliases;
  40.     while (pptr && *pptr != NULL)
  41.     {
  42.         printf("\taliases: %s\n", *pptr);
  43.         pptr++;
  44.     }

  45.     printf("\tport: %d\n", ntohs(sptr->s_port));
  46.     printf("\tproto: %s\n", sptr->s_proto);
  47. }

  48. static void printHostent(struct hostent *hptr)
  49. {
  50.     char str[33] = { 0, };
  51.     char **pptr;

  52.     if (NULL == hptr)
  53.         return;

  54.     printf("Official hostname:%s\n", hptr->h_name);

  55.     for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
  56.         printf("alias:%s\n", *pptr);

  57.     switch (hptr->h_addrtype)
  58.     {
  59.     case AF_INET:
  60.     case AF_INET6:
  61.         pptr = hptr->h_addr_list;
  62.         for (; pptr && *pptr != NULL; pptr++)
  63.             printf("address: %s\n", inet_ntop(hptr->h_addrtype, *pptr, str, 32));
  64.         break;
  65.     default:
  66.         printf("Unknow address type\n");
  67.         break;
  68.     }

  69. }

  70. static void printHerror(int pError)
  71. {
  72.     switch (pError)
  73.     {
  74.     case HOST_NOT_FOUND:
  75.         printf("host not found!\n");
  76.         break;
  77. // case NO_ADDRESS:
  78. // case NO_DATA:printf("112\n");break;
  79.     case NO_RECOVERY:
  80.         printf("no recovery!\n");
  81.         break;
  82.     case TRY_AGAIN:
  83.         printf("try again\n");
  84.         break;
  85.     default:
  86.         printf("unknow error type:%d\n", pError);
  87.         return;
  88.     }
  89. }

  90. void iGethostbyname_common(char *name)
  91. {
  92.     struct addrinfo *answer, hint, *curr;
  93.     char ipstr[16];
  94.     int ret;

  95.     memset(&hint, 0, sizeof(hint));
  96.     hint.ai_flags = AI_CANONNAME;

  97.     ret = getaddrinfo(name, NULL, &hint, &answer);
  98.     if (ret != 0)
  99.     {
  100.         fprintf(stderr, "getaddrinfo fail: %s\n", gai_strerror(ret));
  101.         exit(1);
  102.     }

  103.     for (curr = answer; curr != NULL; curr = curr->ai_next)
  104.     {
  105.         printf("Host name: %s\n", curr->ai_canonname == NULL ? "" : curr->ai_canonname);

  106.         inet_ntop(AF_INET, &(((struct sockaddr_in *)(curr->ai_addr))->sin_addr), ipstr, 16);
  107.         printf("Addr: %s\n", ipstr);
  108.     }

  109.     freeaddrinfo(answer);
  110. }

  111. void iGethostbyname_ipv4(char *name)
  112. {
  113.     struct hostent *hptr;
  114.     if ((hptr = gethostbyname(name)) == NULL)
  115.     {
  116.         printf("gethostbyname fail for host:%s\n", name);
  117.         return;
  118.     }
  119.     printHostent(hptr);
  120. }

  121. void iGethostbyaddr_ipv4(char *addr)
  122. {
  123.     struct hostent *hptr;
  124.     in_addr_t nip;
  125.     int tryTimes = 3;

  126.     nip = inet_addr(addr);

  127.   L_TRY_AGAIN:
  128.     if ((hptr = gethostbyaddr(&nip, 4, AF_INET)) == NULL)
  129.     {
  130.         if (h_errno == TRY_AGAIN && tryTimes > 0)
  131.         {
  132.             tryTimes--;
  133.             goto L_TRY_AGAIN;
  134.         }

  135.         printf("Fail to get host by addr<%s>: ", addr);
  136.         printHerror(h_errno);
  137.         return;
  138.     }
  139.     printHostent(hptr);
  140. }

  141. void iGetservbyname(char *name, char *proto)
  142. {
  143.     struct servent *sptr;

  144.     if ((sptr = getservbyname(name, proto)) == NULL)
  145.     {
  146.         printf("Can NOT find server with name:%s and protocol:%s\n", name, proto);
  147.         return;
  148.     }

  149.     printServent(sptr);

  150. }

  151. void iGetservbyport(int port, char *proto)
  152. {
  153.     struct servent *sptr;

  154.     if ((sptr = getservbyport(htons(port), proto)) == NULL)
  155.     {
  156.         printf("Can NOT find server with port:%d and protocol:%s\n", port, proto);
  157.         return;
  158.     }
  159.     printServent(sptr);
  160. }

  161. char g_buf[64] = { 0, };
  162. char g_proto[16] = { 0, };

  163. int main(int argc, char **argv)
  164. {
  165.     int opt;
  166.     int cmdType = 0;

  167.     int temp = 0;

  168.     if (argc < 2)
  169.     {
  170.         showUsage();
  171.         return 0;
  172.     }

  173.     while ((opt = getopt_long(argc, argv, "s:h:p:", g_opts, NULL)) != -1)
  174.     {
  175.         switch (opt)
  176.         {
  177.         case 's':
  178.             strcpy(g_buf, optarg);
  179.             cmdType = 1;
  180.             break;
  181.         case 'h':
  182.             strcpy(g_buf, optarg);
  183.             cmdType = 2;
  184.             break;
  185.         case 'p':
  186.             strcpy(g_proto, optarg);
  187.             break;
  188.         case 'H':
  189.             showUsage();
  190.             break;
  191.         default:
  192.             showUsage();
  193.             return;
  194.         }
  195.     }

  196.     if (cmdType == 2 && (inet_addr(g_buf)) == INADDR_NONE)
  197.     {
  198.         iGethostbyname_ipv4(g_buf);
  199.     }
  200.     else if (cmdType == 2)
  201.     {
  202.         iGethostbyaddr_ipv4(g_buf);
  203.     }
  204.     else if (cmdType == 1)
  205.     {
  206.         temp = atoi(g_buf);
  207.         if (temp > 0)
  208.             iGetservbyport(temp, g_proto);
  209.         else
  210.             iGetservbyname(g_buf, g_proto);
  211.     }
  212.     else
  213.         showUsage();

  214.     return 0;
  215. }



阅读(2711) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~