1+ #include < iostream>
2+ #include < winsock2.h>
3+ using namespace std ;
4+
5+ #pragma comment(lib,"ws2_32.lib")
6+
7+ void showHostInfo (struct hostent * hostentry){
8+ // 主机名
9+ cout << " the host name is :" << hostentry->h_name << endl;
10+ // 别名序列,内部返回的结构中h_aliases指向的一个char*数组最后一个元素是null(也就是说它至少存在一个元素,下面的对其是否为空的判断也可以省略)
11+ cout << " the alias found : " << endl;
12+ for (char ** alias = hostentry->h_aliases ; alias && *alias; alias++){
13+ cout << *alias << endl;
14+ }
15+ // ip地址类型,目前一般为ipv4
16+ cout << " the address type is : " ;
17+ if (AF_INET == hostentry->h_addrtype ){
18+ cout << " ipv4" << endl;
19+ }else if (AF_INET6 == hostentry->h_addrtype ){
20+ cout << " ipv6" << endl;
21+ }else {
22+ cout << " other address type" << endl;
23+ }
24+ // ip地址的长度,ipv4对应的是4个字节,ipv6为16
25+ cout << " the length of ip is : " << hostentry->h_length << endl;
26+ // ip地址列表,每一个ip之所以使用char*表示,因为不同的协议可能存储格式不同,为了向后兼容,ipv4对应的是一个4字节存储空间(字节顺序是反序的,第一个字节对应的是ip的最低位),也就是如果是ipv4,这里通过每一个char*访问得到的是一个4字节的字符串,存储的内容是大头朝下的ip内存表示
27+ cout << " the ip is : " << endl;
28+ struct in_addr *tmp = nullptr ;
29+ for (char ** ip = hostentry->h_addr_list ; ip && *ip; ip++){
30+ tmp = (struct in_addr *)*ip;// in_addr是一个结构体,里面只有一个int存放ipv4对应的int,这个值为*(unsigned int*)(*ip)
31+ cout << inet_ntoa (*tmp) << endl; // 将二进制(整型)的ip转化为用.分割的常见的ip格式
32+ }
33+ }
34+
35+ int main (){
36+ WSADATA wa;
37+ int error = WSAStartup (MAKEWORD (2 ,2 ),&wa);
38+ if (error){
39+ cout << " init winsock fail" << endl;
40+ exit (-1 );
41+ }
42+ struct hostent * hostentry = gethostbyname (" www.baidu.com" );
43+ if (!hostentry){
44+ cout << " cannot resolve the hostname gived" << endl;
45+ exit (-1 );
46+ }
47+ // 主机名
48+ cout << " the host name is :" << hostentry->h_name << endl;
49+ // 别名序列,内部返回的结构中h_aliases指向的一个char*数组最后一个元素是null(也就是说它至少存在一个元素,下面的对其是否为空的判断也可以省略)
50+ cout << " the alias found : " << endl;
51+ for (char ** alias = hostentry->h_aliases ; alias && *alias; alias++){
52+ cout << *alias << endl;
53+ }
54+ // ip地址类型,目前一般为ipv4
55+ cout << " the address type is : " ;
56+ if (AF_INET == hostentry->h_addrtype ){
57+ cout << " ipv4" << endl;
58+ }else if (AF_INET6 == hostentry->h_addrtype ){
59+ cout << " ipv6" << endl;
60+ }else {
61+ cout << " other address type" << endl;
62+ }
63+ // ip地址的长度,ipv4对应的是4个字节,ipv6为16
64+ cout << " the length of ip is : " << hostentry->h_length << endl;
65+ // ip地址列表,每一个ip之所以使用char*表示,因为不同的协议可能存储格式不同,为了向后兼容,ipv4对应的是一个4字节存储空间(字节顺序是反序的,第一个字节对应的是ip的最低位),也就是如果是ipv4,这里通过每一个char*访问得到的是一个4字节的字符串,存储的内容是大头朝下的ip内存表示
66+ cout << " the ip is : " << endl;
67+ struct in_addr *tmp = nullptr ;
68+ for (char ** ip = hostentry->h_addr_list ; ip && *ip; ip++){
69+ tmp = (struct in_addr *)*ip;// in_addr是一个结构体,里面只有一个int存放ipv4对应的int,这个值为*(unsigned int*)(*ip)
70+ cout << inet_ntoa (*tmp) << endl; // 将二进制(整型)的ip转化为用.分割的常见的ip格式
71+ }
72+
73+ // 类似的,可以使用gethostbyaddr获取到和上面一样的信息
74+ // struct in_addr ia;
75+ // ia.s_addr = inet_addr("183.232.231.174"); //通过字符串类型的ip转换为二进制对应的大头朝下的整型
76+ // cout << ia.s_addr << endl;
77+ struct hostent * hostentry1 = gethostbyaddr ((char *)tmp, 4 , AF_INET ); // 为兼容,传入in_addr*转的char*,ip长度和ip类型
78+ // 上面传入的是百度服务器的ip,使用gethostbyaddr得到的结果是null。对这个结果的解释是,使用ip去查询主机名,这个过程是去查询dns服务器上面的映射文件,和gethostbyname类似,但是一般的dns只是记录了主机-->ip却很少记录ip-->主机。所以gethostbyaddr传入公网ip大部分情况下都是返回null,可以在本地host文件写入ip-->name的映射,这样就可以得到正确的信息了
79+ if (hostentry1)
80+ showHostInfo (hostentry1);
81+ else
82+ cout << " got no message" << endl;
83+
84+ // 下面使用127.0.0.1 获取localhost主机信息。由于这个ip-->name的映射是默认自带的,所以可以返回正常的信息
85+ struct in_addr localhost;
86+ localhost.s_addr = inet_addr (" 127.0.0.1" );
87+ struct hostent * hostentry2 = gethostbyaddr ((char *)&localhost,4 ,AF_INET );
88+ // 返回本地映射信息
89+ if (hostentry2)
90+ showHostInfo (hostentry2);
91+ else
92+ cout << " got no message" << endl;
93+ return 0 ;
94+ }
0 commit comments