Skip to content

Commit f834cf4

Browse files
committed
winsock中gethostbyname和gethostbyaddr两个函数的使用细节
1 parent c08461b commit f834cf4

1 file changed

Lines changed: 94 additions & 0 deletions

File tree

gethostbyname和gethostbyaddr.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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

Comments
 (0)