网编(7):域名及网络地址

版权声明:转载请声明 https://blog.csdn.net/qq_40732350/article/details/88955040

域名系统(Domain Name System)

DNS是对IP地址和域名进行相互转换的系统,其核心是DNS服务器。

什么是域名
提供网络服务的服务器端也是通过IP地址区分的,但几乎不可能以非常难记的IP地址形式交换服务器端地址信息。因此,将容易记、易表述的域名分配并取代IP地址。

DNS 服务器

所有计算机中都记录着默认DNS服务器地址,就是通过这个默认DNS服务器得到相应域名的IP地址信息。在浏览器地址栏中输入域名后,浏览器通过默认DNS服务器获取该域名对应的IP地址信息,之后才真正接入该网站。

计算机内置的默认DNS服务器并不知道网络上所有域名的IP地址信息。若该DNS服务器无法解析,则会询问其他DNS服务器,并提供给用户,如图所示。

默认DNS服务器无法解析主机询问的域名IP地址时的应答过程。可以看出,默认DNS服务器收到自己无法解析的请求时,向上级DNS服务器询问。通过这种方式逐级向上传递信息,到达顶级DN S服务器一一根DNS服务器时,它知道该向哪个DNS服务器询问。向下级DNS传递解析请求,得到[P地址后原路返回,最后将解析的IP地址传递到发起请求的主机。DNS就是这样层次化管理的一种分布式数据库系统。

利用域名获取IP 地址

#include <netdb . h>
struct hostent * gethostbyname(const char * hostname);
#成功时返回hostent 结构体地址,失败时返回NULL 指针。

这个函数使用方便。只要传递域名字符串,就会返回域名对应的IP地址。只是返回时,地址信息装入hostent结构体。此结构体定义如下。

struct hostent{
	char * h_name;         //official name
	char ** h_aliases;     //alias list
	int h_addrtype;        //host address type
	int h_length;          //address length
	char ** h_addr_list;   //address list
}

h_name
该变量中存有官方域名( Official domain name)。官方域名代表某一主页,但实际上, 一些著名公司的域名并未用官方域名注册。
h_aliases
可以通过多个域名访问同一主页。同一IP可以绑定多个域名,因此,除官方域名外还可指定其他域名。这些信息可以通过b_aliases获得。
h_ addrtype
gethostbyname函数不仅支持IPv4, 还支持IPv6 。因此可以通过此变量获取保存在b_addr_list的IP地址的地址族信息。若是IPv4, 则此变量存有AF_INET 。
h_length
保存IP地址长度。若是IPv4地址,因为是4个字节,则保存4; IPv6时, 因为是16个字节,故保存16 。
h_addr_list
这是最重要的成员。通过此变量以整数形式保存域名对应的IP地址。另外,用户较多的网站有可能分配多个IP给同一域名,利用多个服务器进行负载均衡。此时同样可以通过此变量获取IP地址信息。

调用gethostbyname函数后返回的hosten卤i构体的变量结构如图所示,该图在实际编程中非常有用,希望大家结合之前的hostent结构体定义加以理解。

实例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
void error_handling(char *message);
int main(int argc, char* argv[])
{
	int i;
	struct hostent *host;
	if(argc!=2) {
		printf("Usage : %s <addr>\n", argv[0]);
		exit(1);
	}

	host=gethostbyname(argv[1]);
	if(!host)
		error_handling("gethost. . . error");

	printf("Official name : %s \n", host->h_name);
	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");
	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);
}

运行结果:

$ ./a.out www.baidu.com
Official name : www.a.shifen.com 
Aliases 1: www.baidu.com 
Address type: AF_INET 
IP addr 1: 111.13.100.92 
IP addr 2: 111.13.100.91 

利用IP 地址获取域名

#include <netdb.h>
struct hostent * gethostbyaddr(const char* addr, socklen_t len, int family);
//成功时返回hostent 结构体变量地址值,失败时返回NULL 指针

#add 含有IP地址信息的in_addr结构体指针。为了同时传递IPv4地址之外的其他信息,该变量的类型声明为char指针。
#len 向第一个参数传递的地址信息的字节数,IPv4时为4, IPv6时为16。
#family 传递地址族信息,IPv4时为AF_INET, IPv6时为AF_INET6。

用下面的程序:

struct sockaddr_in addr;

addr.sin_addr.s_addr=inet_addr(argv[1]);
host=gethostbyaddr((char*)&addr. sin_addr, 4, AF_INET);

猜你喜欢

转载自blog.csdn.net/qq_40732350/article/details/88955040