Linux网络编程[DNS解析原理,了解相关DNS解析的函数]
2017-05-14 22:39
1296 查看
Linux网络编程[浅析DNS原理,了解相关DNS解析的函数]
1.DNS解析的相关原理2. 域名解析的相关函数
###端口绑定, DNS解析的相关原理
先通过一张图示来展示一下什么是DNS:
1:每一个域名都是与ip进行绑定的
2:浏览器在访问域名的时候,会自动解析出对应绑定的ip地址
3:整个解析过程涉及到域名解析与域名服务器
在自己的本机怎么去进行域名和ip的绑定呢??
linux系统下,可以在本地本间中去设置:
打开/etc/hosts文件:
从我本机的hosts文件中可以看到,对应的ip绑定的主机名和自己设置的域名.第一个域名dean称为正式的主机名字,第二个以后都称为别名
域名解析的相关函数
1**:域名解析函数中的结构体**struct hostent{ char *h_name ;//正式主机名字(第一个域名) char **h_aliases;//主机的别名(主机的别名对应的) int h_addrtype;//协议类型 int h_length;//网络地址大小 char **h_addr_list;//指向网络地址的指针 }; 上述的结构体放置的就是域名解析出来后放置的结构体
从上述图示中可以看出来,h_aliases指向的都是一个数组
h_addr_list指向的也是一个ip地址的数组,所以使用的都是二级指针
2:域名解析相关函数
#include<netdb.h> struct hostent *gethostent(void); //会将整个hosts文件下记录的主机和域名相对应的所有组全部遍历出来 strct hostent *gethostbyname(const char *hostname); 参数:hostname 域名,获取的是指定的hostent 注意: gethostbyname是不支持ipv6的,并且在多线程的情况下是不稳定的.所有一般情况下都是使用gethostent来进行操作的 void sethostent(int stayopen); void endhostent(void);
伪代码案例部分
struct hostnet *hptr; if((hptr = gethostbyname("www.google.com")) == NULL){ printf(stderr,"gethostbyname call failed.%s\n",hosterror(h_errno)); return -1; } //输出h_name(正式域名) printf("offical name:%s\n",hptr->h_name); //输出别名: for(pptr = hptr->h_aliases;*pptr!=NULL,pptr++){ printf("\t aliases:%s\n",*pptr); } //输出网络类型 if(hptr->h_addrtype != AF_INET){ fprintf(stderr,"invalid address type %d\n",hptr->h_addrtype); return -1; } pptr = hptr->h_addr_list; for(;*pptr!=NULL;pptr++){ printf("\t address:%s\n",inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str))); }
gethostbyname部分的实例代码
/* * =========================================================================== * * Filename: gethostbyname.c * Description: * Version: 1.0 * Created: 2017年05月14日 21时52分34秒 * Revision: none * Compiler: gcc * Author: (), * Company: * * =========================================================================== */ #include<stdio.h> #include<stdlib.h> #include<netdb.h> #include<string.h> #include<sys/socket.h> void out_host(struct hostent *h){ //获取主机名称 char *host_name = h->h_name; printf("host_name:%s\n",host_name); //获取网络类型 int host_addrtype = h->h_addrtype; if(host_addrtype == AF_INET){ printf("addrtype:IPV4\n"); }else{ printf("addrtype:IPV6\n"); } //获取主机网络地址的大小 int host_length = h->h_length; printf("host_length:%d\n",host_length); //获取主机的ip,主机的ip对应的是网络地址数组中的0,记住要将网络字节序转换成主机字节序号 char ip[16]; memset(ip,0,sizeof(ip)); inet_ntop(h->h_addrtype,h->h_addr_list[0],ip,sizeof(ip)); printf("host ip:%s\n",ip); //遍历去获取别名 int aliase_count = 0; while( h->h_aliases[aliase_count] != NULL){ printf("host_aliases[%d]:%s\n",aliase_count,h->h_aliases[aliase_count]); aliase_count++; } //获取指向网络地址的数组, int host_addr_list_count = 0; while(h->h_addr_list[host_addr_list_count] != NULL){ memset(ip,0,sizeof(ip)); inet_ntop(h->h_addrtype,h->h_addr_list[host_addr_list_count],ip,sizeof(ip)); printf("host_addr_list[%d]:%s\n",host_addr_list_count,ip); host_addr_list_count++; } } int main(int argc,char *argv[]){ if(argc < 2){ printf("usag %s host \n",argv[0]); exit(EXIT_FAILURE); } struct hostent *h; //通过gethostbyname来获取hostent的结构体指针 h = gethostbyname(argv[1]); if(h == NULL){ printf("no host :%s\n",argv[1]); }else{ out_host(h); } endhostent(); return 0; }
gethostent部分的实例代码
/* * =========================================================================== * * Filename: gethostent.c * Description: * Version: 1.0 * Created: 2017年05月14日 22时14分48秒 * Revision: none * Compiler: gcc * Author: (), * Company: * * =========================================================================== */ #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<netdb.h> #include<sys/socket.h> #include<memory.h> void out_host(struct hostent *h){ //获取主机名称 char *host_name = h->h_name; printf("host_name:%s\n",host_name); //获取网络类型 int host_addrtype = h->h_addrtype; if(host_addrtype == AF_INET){ printf("addrtype:IPV4\n"); }else{ printf("addrtype:IPV6\n"); } //获取主机网络地址的大小 int host_length = h->h_length; printf("host_length:%d\n",host_length); //获取主机的ip,主机的ip对应的是网络地址数组中的0,记住要将网络字节序转换成主机字节序号 char ip[16]; memset(ip,0,sizeof(ip)); inet_ntop(h->h_addrtype,h->h_addr_list[0],ip,sizeof(ip)); printf("host ip:%s\n",ip); //遍历去获取别名 int aliase_count = 0; while( h->h_aliases[aliase_count] != NULL){ printf("host_aliases[%d]:%s\n",aliase_count,h->h_aliases[aliase_count]); aliase_count++; } int host_addr_list_count = 0; while(h->h_addr_list[host_addr_list_count] != NULL){ memset(ip,0,sizeof(ip)); inet_ntop(h->h_addrtype,h->h_addr_list[host_addr_list_count],ip,sizeof(ip)); printf("host_addr_list[%d]:%s\n",host_addr_list_count,ip); host_addr_list_count++; } } int main(int argc,char *argv[]){ if(argc < 2){ printf("usage: %s host\n",argv[0]); exit(EXIT_FAILURE); } struct hostent *h; //因为gethost返回的是一个结构体数组 while((h = gethostent()) != NULL){ if(strcmp(argv[1],h->h_name) == 0){ out_host(h); }else{ int aliases_count = 0; while(h->h_aliases[aliases_count] != NULL){ if(strcmp(argv[1],h->h_aliases[aliases_count]) == 0){ out_host(h); exit(EXIT_FAILURE); } aliases_count++; } } } endhostent(); return 0; }
以上除了伪代码部分,gethostbyname.c个gethostent.c的代码都是直接可以进行run的,在使用的时候相对来说是比较推荐去使用gethostent的,因为gethostbyname不支持ipv6以及不建议在多线程情况下去使用的.当然,这也只是简单的去了解下dns去在解析的时候的简单的原理.
欢迎持续访问博客
相关文章推荐
- linux网络编程函数解析(1)--setsockopt
- 网络编程相关函数深层次解析
- linux网络编程函数解析(1)--setsockopt(
- Linux 网络编程基础(1)--网络相关的数据结构及转化函数
- [Linux网络编程]以太网封装格式及相关结构体
- Linux网络编程:4. 完整的读写函数
- Linux网络编程之connect函数分析
- 【linux内核2.4.26·网络】IP分片重组过程函数解析
- Linux网络编程常用信息 结构 格式化 函数 等
- linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)
- Linux下的网络函数gethostbyname/gethostbyaddr会访问DNS吗?
- linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)
- Linux网络编程常用函数
- linux下网络编程之相互转化函数对
- 网络编程常见函数解析
- 网络编程相关函数说明
- Linux下的管道编程技术-dup函数和dup2函数(网络资源)
- 【嵌入式Linux学习七步曲之第七篇 Linux的高级应用编程】TCP/IP网络编程函数解析
- 嵌入式linux网络编程之connect()函数的高级应用
- Linux网络相关配置(IP配置\DNS配置等)