今天又学习了下winsock的知识,对知识做一下梳理。
1. 域名系统简介:Domain Name System(DNS)
其一个明显的作用是简化人们对IP的记忆方式,比如新浪的域名:www.sina.com,IP地址为“202,108,33,32”。
这IP地址多难记啊。
DNS空间是一个树形结构,树中的节点对应着一个资源集合,每个集合中包含一个或者多个资源记录,描述了与这个
节点名字相关的信息,其他主机可以通过查询操作得到指定资源集合中的具体信息。
1.1 解析器:
对于用户,接触最多的就是解析器,解析器是用户程序与域名服务器之间的接口程序,一般是库函数或系统调用。
当我们在收发邮件或者使用网页时都在使用解析器提供的服务,他把我们输入的名字转换为IP地址。实际上,
我们在地址栏输入“202,108,33,32”也可以访问新浪。
1.2 域名系统模型:
下图显示了应用程序、解析器、和名字服务器之间的典型关系:
主机查询程序 :
#include<stdlib.h> #include<stdio.h> #include<winsock2.h> #pragma comment(lib,"ws2_32") //注入要使用的库文件 int main(int argc ,char *argv[]) { char *name = NULL,**list_p; struct hostent *hostent_p; struct in_addr addr; WSADATA wsaData; WSAStartup(MAKEWORD(2,0),&wsaData);//winsock初始化 if(argc == 2) //命令行输入的第二个参数是要解析的主机名或地址 { name = argv[1]; } if(name && isdigit(name[0]))//如果name[0]是数字,表示刚才输入的是IP地址 { addr.s_addr = inet_addr(name);//地址转换函数,在上一篇中有代码实现 if(addr.s_addr == INADDR_NONE)//输入的格式错误 { printf("[%s] is invaild address\n",name); return -1; } hostent_p = gethostbyaddr((char *)&addr,sizeof(addr),AF_INET); } else //输入的不是数字,是字符串,表示输入的是主机名 hostent_p = gethostbyname(name);//得到主机信息 if(hostent_p == NULL) { printf("fail to lookup,error:%d\n",WSAGetLastError()); return -1; } printf("offical name :%s\n",hostent_p->h_name);//输出主机名称 //如果主机还有别名,输出所有别名 if(*hostent_p->h_aliases) printf("alias:\n"); for(list_p = hostent_p->h_aliases;*list_p != NULL;list_p++) { printf("\t%s\n",*list_p); } //根据地址类型(不同的地址类型如IPV4,IPV6,其他类型用unknown表示),将地址打印出来 switch(hostent_p->h_addrtype) { case AF_INET: printf("address type : AF_INET\n"); break; case AF_INET6: printf("address type : AF_INET6\n"); break; default: printf("address type is unknown\n"); return -1; } printf("address:\n"); for(list_p = hostent_p->h_addr_list;*list_p != NULL; list_p++) { memcpy(&addr.S_un.S_addr,*list_p,hostent_p->h_length);//从list_p所指的内存地址拷贝hostent_p->h_length长的字节到&addr.S_un.S_addr(地址) printf("\t%s\n",inet_ntoa(addr)); } WSACleanup();//释放资源 return 0; }
运行结果: