五十7、linux 編程——UDP 編程 域名解析

57.1 介紹

57.1.1 域名解析

  

57.1.2 域名解析函數

  

  gethostent 能夠獲取多組,gethostbyname 只能夠獲取一組服務器

  /etc/hosts 文件設置了域名和 IP 的綁定關係多線程

  

  

57.2 例子

57.2.1 例子1

  gethost.csocket

 1 #include <netdb.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <memory.h>
 5 #include <arpa/inet.h>
 6 
 7 
 8 void out_addr(struct hostent *h)  9 { 10     printf("hostname: %s\n", h->h_name); 11     printf("addrtype: %s\n", h->h_addrtype == AF_INET ? "IPV4": "IPV6"); 12     char ip[16]; 13     memset(ip, 0, sizeof(ip)); 14     inet_ntop(h->h_addrtype, h->h_addr_list[0], ip, sizeof(ip)); 15     printf("ip address: %s\n", ip); 16 
17     int i = 0; 18     while(h->h_aliases[i] != NULL){ 19         printf("aliase: %s\n", h->h_aliases[i]); 20         i++; 21  } 22 } 23 
24 int main(int argc, char *argv[]) 25 { 26     if(argc < 2){ 27         printf("usage: %s host\n", argv[0]); 28         exit(1); 29  } 30 
31     struct hostent *h; 32     h = gethostbyname(argv[1]); 33     if( NULL != h){ 34  out_addr(h); 35  } 36     else{ 37         perror("get hostbyname error"); 38  } 39 
40     return 0; 41 }

  修改下 /etc/hosts 文件,給 localhost 增長一個別名函數

  

  編譯運行:測試

  

  gethostbyname 有一些缺陷,支持 IPV4 可是不支持 IPV6,且不能用於多線程中。spa

57.2.2 例子2

  gethost2.c線程

 1 #include <netdb.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <memory.h>
 5 #include <arpa/inet.h>
 6 
 7 
 8 void out_addr(struct hostent *h)  9 { 10     printf("hostname: %s\n", h->h_name); 11     printf("addrtype: %s\n", h->h_addrtype == AF_INET ? "IPV4": "IPV6"); 12     char ip[16]; 13     memset(ip, 0, sizeof(ip)); 14     inet_ntop(h->h_addrtype, h->h_addr_list[0], ip, sizeof(ip)); 15     printf("ip address: %s\n", ip); 16 
17     int i = 0; 18     while(h->h_aliases[i] != NULL){ 19         printf("aliase: %s\n", h->h_aliases[i]); 20         i++; 21  } 22 } 23 
24 int main(int argc, char *argv[]) 25 { 26     if(argc < 2){ 27         fprintf(stderr, "usage: %s host\n", argv[0]); 28         exit(1); 29  } 30 
31     struct hostent *h; 32     while((h = gethostent()) != NULL){ 33         if(!strcmp(argv[1], h->h_name)){ 34  out_addr(h); 35             exit(0); 36  } 37         else{ 38             int i = 0; 39             while(h->h_aliases[i] != NULL){ 40                 if(!strcmp(argv[1], h->h_aliases[i])){ 41  out_addr(h); 42                     exit(0); 43  } 44                 i++; 45  } 46  } 47  } 48 
49  endhostent(); 50     printf("no %s exist\n", argv[1]); 51 
52     return 0; 53 }

  編譯運行:3d

  

57.2.3 例子3

  修改前面 time_udp_client.c 文件code

 1 #include <sys/types.h>
 2 #include <sys/socket.h>
 3 #include <arpa/inet.h>
 4 #include <unistd.h>
 5 #include <netdb.h>
 6 #include <stdio.h>
 7 #include <stdlib.h>
 8 #include <signal.h>
 9 #include <string.h>
10 #include <time.h>
11 
12 int is_host(struct hostent *host, char *name) 13 { 14     if(!strcmp(host->h_name, name)) return 1; 15     int i = 0; 16     while(host->h_aliases[i] != NULL){ 17         if(!strcmp(host->h_aliases[i], name)) return 1; 18         i++; 19  } 20 
21     return 0; 22 } 23 
24 unsigned int get_ip_by_name(char *name) 25 { 26     unsigned int ip = 0; 27     struct hostent *host; 28     while((host = gethostent()) != NULL){ 29         if(is_host(host, name)){ 30             memcpy(&ip, host->h_addr_list[0], 4); 31             break; 32  } 33  } 34 
35  endhostent(); 36     return ip; 37 } 38 
39 int main(int argc, char *argv[]) 40 { 41     if(argc < 3){ 42         printf("usage: %s ip port\n", argv[0]); 43         exit(1); 44  } 45 
46     /** 步驟1: 建立 socket */
47     int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 48     if(sockfd < 0){ 49         perror("socket error"); 50         exit(1); 51  } 52 
53     /** 步驟2: 調用 recvfrom 和 sendto 等函數和服務器端雙向通訊 */
54     struct sockaddr_in serveraddr; 55     memset(&serveraddr, 0, sizeof(serveraddr)); 56     serveraddr.sin_family = AF_INET; ///< ipv4 57  serveraddr.sin_port = htons(atoi(argv[2])); ///< port 58     
59     unsigned int ip = get_ip_by_name(argv[1]); 60     if(ip != 0){ 61         serveraddr.sin_addr.s_addr = ip; 62  } 63     else { 64         inet_pton(AF_INET, argv[1], &serveraddr.sin_addr.s_addr); 65  } 66     
67     char buffer[1024] = "hello world"; 68     /** 向服務器端發送數據報文 */
69     if(sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0){ 70         perror("sendto error"); 71         exit(1); 72  } 73     else{ 74         /** 接受服務器端發送的數據報文 */
75         memset(buffer, 0, sizeof(buffer)); 76         if(recv(sockfd, buffer, sizeof(buffer), 0) < 0){ 77             perror("recv error"); 78             exit(1); 79  } 80         else{ 81             printf("%s", buffer); 82  } 83  } 84 
85  close(sockfd); 86 
87     return 0; 88 }

  編譯,運行服務器和客戶端測試:server

  

相關文章
相關標籤/搜索