DNS域名和网络地址

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

域名:提供网络服务的服务器端也是通过IP地址区分的,IP地址非常难记。因此将容易记、易表述的域名分配取代IP地址。

DNS服务器:域名是赋予服务器端的虚拟地址,而非实际地址。因此,需要将虚拟地址转化为实际地址。那如何将域名变为IP地址呢?可以向DNS服务器请求转换地址。

       所有计算机中都记录着默认DNS服务器地址,就是通过这个默认DNS服务器得到相应域名的IP地址信息。在浏览器地址栏中输入域名后,浏览器通过默认DNS服务器获取该域名对应的IP地址信息,之后真正的接入网站。
       计算机内置的默认DNS服务器并不知道网络上所有域名的IP地址信息。若该DNS服务器无法解析,则会询问其他DNS服务器,并提供给用户。因为DNS是层次化管理的一种分布式数据库系统,当默认DNS服务器收到自己无法解析的请求时,向上级DNS服务器询问。通过这种方式逐级向上传递信息,达到顶级DNS服务器----根DNS服务器时,它知道向哪个DNS服务器询问。

IP地址和域名之间的转换
1、利用域名获取IP地址
使用以下函数可以通过传递字符串格式的域名获取IP地址

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

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

struct hostent
{
     char*  h_name;     //官方域名
     char** h_aliases;  
     int    h_addrtype; //地址类型 
     int    h_length;   //地址长度
     char** h_addr_list;//地址列表  
}

h_name----该变量中存有官方域名
h_aliases----可以通过多个域名访问同一主页,同一IP可以绑定多个域名。因此,除了官方域名外还可指定其他域名,这通过h_aliases获得
h_addrtype----gethostbyname函数不仅支持IPv4还支持IPv6,因此可以通过此变量获取保存在h_addr_list的IP地址的地址族信息。若是IPv4,则此变量存有AF_INET。
h_length----保存IP地址长度。若是IPv4,4个字节,保存4;IPv6时,因为16个字节,故保存16
h_addr_list----通过此变量以整数形式保存域名对应的IP地址。

#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,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);
}

2、利用IP地址获取域名
gethostbyaddr函数利用IP地址获取域名相关信息

 

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

addr---含有IP地址信息的in_addr结构体指针
len---向第一个参数传递的地址信息的字节数,IPv4时为4,IPv6时为16
family---传递地址族信息,IPv4时为AF_INET,IPv6时为AF_INET6

 

#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 i;
   struct hostent *host;
   struct sockaddr_in addr;
   if(argc!=2){
      printf("Usage:%s<IP>\n",argv[0]);
      exit(1);
   }
   
   memset(&addr,0,sizeof(addr));
   addr.sin_addr.s_addr=inet_addr(argv[1]);
   host=gethostbyaddr((char*)&addr.sin_addr,4,AF_INET);
   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);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值