网络编程(8)—— IP地址和域名之间的转换
来源:互联网 发布:松岗卓翼科技工资算法 编辑:程序博客网 时间:2024/04/28 07:26
一、引言
域名,简单来理解就是我们平常说的网址。比如登录某度买假药时,会在IE浏览器的地址栏输入www.baidu.com,这里我们输入的就是百度的域名。而实际上我们在互联网中要找到某个网站,是需要这个网站的IP地址的,因为在网络中IP地址就是一台主机的联系地址,而通过域名寻找主机时,就需要先将域名转换成IP地址,这就是我们通常说的DNS服务器的作用。
二、通过域名获取IP地址
网络编程中,我们通过gethostbyname函数可以通过域名获取主机信息。所谓主机信息就是网络那头web服务器的信息,其中就包含该服务器的IP地址。gethostbyname的函数原型如下:
#include <netdb.h>struct hostent *gethostbyname(const char *name);它接收的唯一参数就是我们在浏览器中输入的域名,在前面的例子中也就是某度的url:www.baidu.com。而他的返回值是一个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 保存的是h_addr_list中IP地址的类型。AF_INET表示IPv4类型的地址,AF_INET6表示IPv6类型的地址,这个大家应该很熟悉吧,就是我们在创建socket时采用的协议族类型。
h_length,保存的IP地址的长度。若是IPv4,因是4个字节,该值是4;若是IPv6,保存的是16个字节,该值是16;
h_addr_list,保存的是IP地址的列表。因为同一个域名可能分配给了多个IP地址,以缓解用户访问的压力,所以这里包含了多个IP地址。但是,值得注意的是,这里面保存的并不是字符串类型的IP地址,而是in_addr结构体变量的地址,也就是说h_addr_list实际上保存的是指针(为了兼容后续的IPv6d地址信息的指针,这里面的指针类型是char* ,而非in_addr*),指向了了in_addr结构体对象,而in_addr包含了IP地址信息。如果我们想要把in_addr结构体变成我们熟悉的点分十进制格式的IP地址,可以借助inet_ntoa()函数,用法请参照后面的例子。
下面是in_addr结构体的定义:
strcut in_addr{ in_addr_t s_addr; //32 位的IPv4地址 }
接下来,是一个gethostbyname使用实例,我们来获取某度的IP地址:
#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 <port>",argv[0]); exit(1); } host=gethostbyname(argv[1]); if(!host) { error_handling("gethostbyname error"); } printf("official name is %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(0);}
结果如下,发现该度设置了两个IP地址,分别是14.215.177.38和14.215.177.37.
我们在浏览器里可以直接输入ip地址来访问该度:
三、利用IP地址获取域名
想利用IP地址获取域名,使用gethostbyaddr函数:
#include <netdb.h>##include <sys/socket.h> /* for AF_INET */struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);
addr,指向in_addr结构体变量的指针。通过id地址获取in_addr结构体变量,相信大家都应该猜到了吧,就是inet_addr("14.215.177.37")。
len,输入的IP地址的长度,单位为字节,若是IPv4该值为4,若是IPv6该值为16
type,IP地址的类型,IPv4:AF_INET,IPv6:AF_INET6
我们再利用上面获得的ip地址获取百度的域名,使用实例如下:
#include<stdlib.h>#include<stdio.h>#include<string.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; struct sockaddr_in addr; if(argc!=2) { printf("Usage %s <port>",argv[0]); exit(1); } memset(&addr,0,sizeof(addr)); addr.sin_addr.s_addr=inet_addr(argv[1]); host=gethostbyaddr((char*)&addr.sin_addr.s_addr,4,AF_INET); if(!host) { error_handling("gethostbyaddr error"); } printf("official name is %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(0);}
结果:
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL08
- 网络编程(8)—— IP地址和域名之间的转换
- IP地址与域名之间的转换(Linux + GCC)
- ASP.NET2.0中IP地址和域名之间的转换
- linux c 网络编程:用域名获取IP地址或者用IP获取域名 网络地址转换成整型 主机字符顺序与网络字节顺序的转换
- java网络编程-获取域名和ip地址
- 网络DNS域名转换成IP地址
- 网络编程—获取自己的ip地址和域名解析
- C# IP地址和整数之间的转换,IP地址和数字ip地址的转换
- 利用Java完成域名和IP地址的转换
- 域名IP地址转换
- 网络编程(30)—— IP地址分类和子网掩码的作用
- (四十八)socket编程——引入、网络字节序、IP地址转换函数、sockaddr数据结构
- 获取网络域名的IP地址
- IP地址与域名之间的转换(Windows + Visual Studio 2015)
- Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip
- IP 地址和 Int 型之间的转换
- python IP 地址和数字之间的转换
- IP 地址和 Int 型之间的转换
- 唐灵波_2015级精英班_2015~2016第一学期总结
- Timer和TimerTask总结
- 配置nagios监控oracle,check_oracle_health
- 基于Netty 的webSocket开发
- HTTP协议1
- 网络编程(8)—— IP地址和域名之间的转换
- 有些东西再忙也要做
- 第36篇 翻译webrtc官方文档(三)及PHP命名空间(二)
- POJ 1077(HDU 1043)Eight(八数码DBFS)
- LNK2001:unresolved external symbol "struct Distance Distance_struct"(?Distance_struct@@3UDistance@@A
- 七种网卡绑定模式
- 【33.18%】【hdu 5877】Weak Pair (3种解法)
- 《javascript高级程序设计》——变量和作用域
- memcache 提高命中率, memcached server LRU 深入分析