TCP/IP网络编程 学习笔记_9 --域名系统(DNS)
2015-08-12 19:38
771 查看
域名系统
什么是域名:我们网络通信底层最终还是通过IP地址来确认通信目标的,但以数字命名的IP地址非常难记,因此,我们就有了容易记,易表述的域名来取代IP地址。如,百度域名就是:www.baidu.com,而它的IP地址为:180.97.33.107,用这两种任何一种访问都是一样的效果。DNS服务器:
1,DNS即Domain Name System,它是一个可以对IP地址和域名进行相互转换的系统。
2,我们要打开一个网页,一般过程是:在浏览器地址栏输入域名地址(www.baidu.com),确认访问,然后它就会通过计算机默认的DNS服务器将这个域名地址转换为对应的IP地址信息,之后才能真正接入该网站。
然而,计算机内置的默认DNS服务器并不知道网络上所有域名的IP地址信息。若该DNS服务器无法解析,则会询问其他DNS服务器。这个过程是这样的:当默认DNS服务器收到自己无法解析的请求时,它会向上级DNS服务器询问,一层一层逐级向上传递信息,直到到达顶级DNS服务器(根DNS服务器)时,它就知道该向哪个DNS服务器询问。然后,向下级DNS传递解析请求,得到IP地址后原路返回,最后将解析的IP地址传递到发起请求的主机。DNS就是这样层次化管理的一种分布式数据库系统。示意图如下:
3,小操作:
如果想知道某一域名对应的IP地址信息,我们可以在控制台窗口输入如下内容:ping www.baidu.com
ping命令虽然是用来验证IP数据报是否到达目的地的,但执行过程中会同时经过域名到IP地址的转换过程,因此,可以通过此命令查看IP地址。
如果想知道自己计算机中注册的默认DNS服务器地址,可以输入如下命令:nslookup(如果是Linux系统,还需要进一步输入server)
IP地址和域名之间的转换
程序中为什么多选择使用域名而不是IP,这是因为一般IP地址容易变更。如果这样,那么一旦IP发生变化,用户就得重新下载你的应用程序了。所以用域名,一般域名注册了就可能永远不变,这样,每次运行程序时根据域名获取IP地址,再接入服务器,这样程序就不会依赖于服务器IP地址了。下面,我们就来分别看看IP与域名之间到底怎么转换。利用域名获取IP地址
struct hostent * gethostbyname(const chat *hostname);
成功时返回hostent结构体地址,失败返回NULL指针
hostname:域名字符串
struct hostent
{
char * h_name; //官方域名
char ** h_aliases; //其它域名,同一IP可以绑定多个域名
int h_addrtype; //地址族信息
int h_length; //IP地址长度,是IPv4则保持4,IPv6则保持16字节
char ** h_addr_list; //整数形式保存域名对应的IP地址,用户较多的网站可能分配多个IP给同一域名,利用多个服务器进行负载均衡。
}
实例代码:
// // main.cpp // hello_client // // Created by app05 on 15-8-12. // Copyright (c) 2015年 app05. All rights reserved. // #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <netdb.h> void error_handling(char *message); int main(int argc, const char * argv[]) { int i; struct hostent *host; if (argc != 3) { printf("Usage: %s <addr> \n", argv[0]); exit(1); } //域名转IP host = gethostbyname("www.baidu.com"); if(!host) error_handling("gethost ... error"); //官方域名 printf("Official name: %s \n", host->h_name); //其它域名(同一IP可以对应多个域名) for (i = 0; host->h_aliases[i]; i++) { printf("Aliases %d: %s \n", i + 1, host->h_aliases[i]); } //地址族类型 printf("Address type: %s \n", (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6"); //IP地址(同一域名可以对应多个IP,负载均衡) for (i = 0; host->h_addr_list[i]; i++) { printf("IP addr %d: %s \n", i+1, inet_ntoa(*(struct in_addr *)host->h_addr_list[i])); } return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }
利用IP地址获取域名(有时一些IP获取返回NULL,可能因为路由等问题。。。做了限制。。。)
struct hostent * gethostbyaddr(const char *addr, socklen_t len, int familly);
成功时返回hostent结构体变量地址值,失败时返回NULL指针
实例代码:
// // main.cpp // hello_client // // Created by app05 on 15-8-12. // Copyright (c) 2015年 app05. All rights reserved. // #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <netdb.h> void error_handling(char *message); int main(int argc, const char * argv[]) { int i; struct hostent *host; struct sockaddr_in addr; if (argc != 3) { printf("Usage: %s <addr> \n", argv[0]); exit(1); } memset(&addr, 0, sizeof(addr)); addr.sin_addr.s_addr = inet_addr("216.58.221.36"); //IP转域名 host = gethostbyaddr((char *) &addr.sin_addr, 4, AF_INET); if(!host) error_handling("gethost ... error"); //官方域名 printf("Official name: %s \n", host->h_name); //其它域名(同一IP可以对应多个域名) for (i = 0; host->h_aliases[i]; i++) { printf("Aliases %d: %s \n", i + 1, host->h_aliases[i]); } //地址族类型 printf("Address type: %s \n", (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6"); //IP地址(同一域名可以对应多个IP,负载均衡) for (i = 0; host->h_addr_list[i]; i++) { printf("IP addr %d: %s \n", i+1, inet_ntoa(*(struct in_addr *)host->h_addr_list[i])); } return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }
扩展:上面两个转换函数的很多参数或返回值结构体中地址信息都定义为(char*)类型,而不是直接in_addr类型。是因为这两个函数不光是为IPv4设定的,还可以是IPv6。因此,考虑通用性,声明类型为char指针类型的数组。其实,对于指针所指对象不明确时,使用(void *)类型更合理,只是因为当时定义这些函数时,void指针标准还没出来。
struct in_addr
{
In_addr_t s_addr; //4字节IPv4地址
}
相关文章推荐
- TCP/IP网络编程 学习笔记_9 --域名系统(DNS)
- 黑马程序员——java学习14(毕23-24)——网络编程
- http服务器交互get,put,post,delete等概念
- 网络篇----数据安全
- iOS安全系列之一:HTTPS
- Android网络取数据显示到ListView实例
- 卷积神经网络(CNN)笔记
- TCP/IP、Http、Socket的区别
- Http 异步批量下载图片之优化
- IOS--http状态码快速查看
- iOS安全系列之 HTTPS
- android中Http和HttpClient的Get和Post方法的使用
- http异步大量图片下载,并用GridView显示九宫格图片样式
- 通过http user-agent判断是否为手机浏览器
- 运行中修改协调器PAN ID和Channel,协调器广播至所有的设备重启加入新建后的网络
- MFC快速实现网络编程CAsyncSocket类
- 计算机网络之面试常考
- 计算机网络之面试常考
- linux网络设备—PHY
- http状态码301和302详解及区别——辛酸的探索之路