一、 数据结构struct hostent
GNU C库的头文件netdb.h中关于struct hostent定义如下:
/* Description of data base entry for a single host. */ struct hostent { char *h_name; /* Official name of host. */ char **h_aliases; /* Alias list. */ int h_addrtype; /* Host address type. */ int h_length; /* Length of address. */ char **h_addr_list; /* List of addresses from name server. */ #ifdef __USE_MISC # define h_addr h_addr_list[0] /* Address, for backward compatibility.*/ #endif };
char *h_name: The official name of the host,表示的是主机的规范名。
char **h_aliases: An array of alternative names for the host, terminated by a null pointer,表示的是主机的别名。
int h_addrtype: The type of address; always AF_INET or AF_INET6 at present,表示的是主机ip地址的类型。ipv4为AF_INET,ipv6为AF_INET6。
int h_length: The length of the address in bytes,表示的是主机ip地址的长度。
char **h_addr_list: An array of pointers to network addresses for the host (in network byte order), terminated by a null pointer,表示的是主机的ip地址,注意,这个是以网络字节序存储的。
二、 获取主机信息函数gethostbyname和gethostbyaddr
1、 struct hostent * gethostbyname (const char *name)
The gethostbyname function returns information about the host named name. If the lookup fails, it returns a null pointer.
2、 struct hostent * gethostbyaddr (const void *addr, socklen_t length, int format)
The gethostbyaddr function returns information about the host with Internet address addr. The parameter addr is not really a pointer to char – it can be a pointer to an IPv4 or an IPv6 address. The length argument is the size (in bytes) of the address at addr. format specifies the address format; for an IPv4 Internet address, specify a value of AF_INET; for an IPv6 Internet address, use AF_INET6.
If the lookup fails, gethostbyaddr returns a null pointer.
三、 获取主机信息实例
#include <stdio.h> #include <stdlib.h> #include <netdb.h> #include <arpa/inet.h> int main(int argc, char **argv) { struct sockaddr_in addr; struct hostent *host = NULL; // 输入参数有误 if (argc != 2) { printf("USAGE:\t%s IP Adress | Domain Name\n", argv[0]); return 1; } // 输入为IP地址 inet_aton(argv[1], &addr.sin_addr); host = gethostbyaddr((void *) &addr.sin_addr, 4, AF_INET); // 输入为域名 if (host == NULL) { host = gethostbyname(argv[1]); } // 输入信息不能解析 if (host == NULL) { printf("Input Data Error !\n"); return 1; } printf("Input Data:\t%s\n", argv[1]); printf("Official Name:\t%s\n", host->h_name); for (int i = 0; host->h_aliases[i]; i++) { printf("Alias List%d:\t%s\n", i, host->h_aliases[i]); } printf("Address Type:\t%s\n", host->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6"); printf("Address Length:\t%d\n", host->h_length); for (int i = 0; host->h_addr_list[i]; i++) { printf("Address List%d:\t%s\n", i, inet_ntoa(*(struct in_addr *) host->h_addr_list[i])); } return 0; }
运行结果如下:
[ycxie@fedora Workspace]$ gcc gethost.c -o gethost -Wall [ycxie@fedora Workspace]$ [ycxie@fedora Workspace]$ ./gethost www.xieyincai.com Input Data: www.xieyincai.com Official Name: xieyincai.com Alias List0: www.xieyincai.com Address Type: AF_INET Address Length: 4 Address List0: 107.180.58.57 [ycxie@fedora Workspace]$ [ycxie@fedora Workspace]$ ./gethost www.mit.edu Input Data: www.mit.edu Official Name: e9566.dscb.akamaiedge.net Alias List0: www.mit.edu Alias List1: www.mit.edu.edgekey.net Address Type: AF_INET Address Length: 4 Address List0: 23.220.180.92 [ycxie@fedora Workspace]$ [ycxie@fedora Workspace]$ ./gethost www.gov.cn Input Data: www.gov.cn Official Name: uz91.v.qingcdn.com Alias List0: www.gov.cn Alias List1: www.gov.cn.qingcdn.com Address Type: AF_INET Address Length: 4 Address List0: 124.239.161.141 Address List1: 124.239.161.142 Address List2: 124.239.161.145 Address List3: 124.239.161.146 Address List4: 124.239.161.144 Address List5: 124.239.161.139 Address List6: 124.239.161.140 Address List7: 124.239.161.143 [ycxie@fedora Workspace]$ [ycxie@fedora Workspace]$ ./gethost 8.8.8.8 Input Data: 8.8.8.8 Official Name: google-public-dns-a.google.com Address Type: AF_INET Address Length: 4 Address List0: 8.8.8.8