五十七、linux 编程——UDP 编程 域名解析

57.1 介绍

57.1.1 域名解析

  

57.1.2 域名解析函数

  

  gethostent 可以获取多组,gethostbyname 只可以获取一组

  /etc/hosts 文件设置了域名和 IP 的绑定关系

  

  

57.2 例子

57.2.1 例子1

  gethost.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
", h->h_name);
11     printf("addrtype: %s
", 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
", ip);
16 
17     int i = 0;
18     while(h->h_aliases[i] != NULL){
19         printf("aliase: %s
", 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
", 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,且不能用于多线程中。

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
", h->h_name);
11     printf("addrtype: %s
", 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
", ip);
16 
17     int i = 0;
18     while(h->h_aliases[i] != NULL){
19         printf("aliase: %s
", 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
", 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
", argv[1]);
51 
52     return 0;
53 }

  编译运行:

  

57.2.3 例子3

  修改前面 time_udp_client.c 文件

 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
", 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 }

  编译,运行服务器和客户端测试:

  

原文地址:https://www.cnblogs.com/kele-dad/p/10510267.html