一:域名解析的定义
域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转换过程。域名的解析工作由DNS服务器完成。
二:为什么要域名解析?
我们登录网站一般都是输入网站的域名,他的IP地址我们很少能记住,并且一个网站的IP地址不只有一个,有些网站的IP地址经常还会有变动,就算已经记住了,我们下一次访问时有可能就找不到相应的网站了。baidu.com是我们大家都知道的百度网站的域名,但是他的IP地址我们却很少有人知道,所以使用域名可以让我们更加方便快速的进入一个网站。
三:socket域名解析的操作
1:gethostbyname()函数
#include <netdb.h>
#include <sys/socket.h>
struct hostent *gethostbyname(const char *name);
使用该函数时,传入参数为const char *name,即要解析的域名(如www.baidu.com)就会返回域名对应的IP地址,函数的返回值为hostent类型的结构体。
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
h_name是主机的规范名。例如www.baidu.com的规范名其实是www.a.shifen.com。
h_aliases是主机的别名,可以通过多个域名访问同一主机。www.baidu.com就是baidu他自己的别名。
h_addrtype是主机ip地址的类型。
h_length是主机ip地址的长度。
h_addr_list表示的是主机的ip地址。是网络字节序,需要通过inet_ntop函数转换。
char **h_aliases即为我们想要的IP地址,但是我们还需要用inet_ntop()函数,将点分文本的IP地址转换为二进制网络字节序的IP地址。
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
此将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。返回指向dst的一个指针。如果函数调用错误,返回值是NULL。
(2)getaddrinfo()函数
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,struct addrinfo **res);
const char *node为主机名,const char *service为端口号或服务名、const struct addrinfo *hints为一个空指针或指向一个addrinfo结构的指针,struct addrinfo **res是存放返回addrinfo结构链表的指针。
addrinfo的结构体
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
sockaddr *ai_addr就是我们需要的IP地址,需要注意的是,我们需要的是IPv4,所以我们还需要把sockaddr类型转化转换为sockaddr_in来使用。
示例:
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME;
hints.ai_protocol =0;
ret = getaddrinfo(h_name, NULL, &hints, &result);