域名解析函数 gethostbyname

在实现TCP/UDP编程的时候,服务端绑定的IP地址是点分十进制的,如124.222.215.205,如果提供的是域名,此时我们需要将域名转换成点分十进制的IP地址,这个过程就是 “ 域名解析 ”,实现域名转换的函数就是 gethostbyname。


目录

1、gethostbyname

2、hostent结构体成员 h_addr_list 

3、使用 gethostbyname 函数解析域名

(1) 获取到主机相关信息

(2) 将主机结构体信息中的网络字节序IP转换成本地字节序IP

(3) 完整代码


1、gethostbyname

gethostbyname 函数的作用是获取主机的相关信息,这里的相关信息就包含主机的IP地址。我们需要重点了解的是这个函数的返回值。

域名解析函数 gethostbyname_第1张图片

 参数name:输入域名或者IP地址

返回值:失败返回NULL,同时 h_errno 会被设置,注意普通函数报错设置的是errno,gethostbyname 函数出错设置的是herror,我们可以通过 hstrerror 函数来获取h_errno对应的错误信息。

成功返回一个结构体,主机的IP地址就放在最后一个参数 h_addr_list 中,h_addr_list 中存放的IP地址是32位网络字节序的整数。

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 */
}

2、hostent结构体成员 h_addr_list 

你或许会觉得好奇,为什么输入一个域名会得到一个IP地址列表?一个域名可能只是一个服务器集群的入口,这里得到的IP地址列表,其实是一个集群中不同服务器的虚拟IP。

域名解析函数 gethostbyname_第2张图片

为了便于向后兼容,Linux系统将IP地址列表中的第一个地址定义成宏 h_addr,在使用时我们可以直接获取 h_addr 的值来作为解析后的结果,注意,这里的 h_addr 也是32位网络字节序

3、使用 gethostbyname 函数解析域名

下面就使用 gethostbyname 函数来解析百度域名(www.baidu.com)

(1) 获取到主机相关信息

struct hostent* hs = gethostbyname("www.baidu.com");
if(hs == NULL)
{
    herror("gethostbyname");
    return 1;
}

(2) 将主机结构体信息中的网络字节序IP转换成本地字节序IP

struct in_addr in;
in.s_addr =*((uint32_t*)hs->h_addr_list[0]);
char* addr = inet_ntoa(in);        // 网络字节序转本地字节序

(3) 完整代码

#include 
#include 
#include 
#include 
#include 
#include 

int main(){
  // 解析域名,获取到主机信息
  struct hostent* hs = gethostbyname("www.baidu.com");    
  if(hs == NULL)    
  {
    herror("gethostbyname");
    return 1;
  }

  struct in_addr in;
  in.s_addr =*((uint32_t*)hs->h_addr_list[0]);    
  // 将主机信息中的网络字节序IP转换成本地字节序IP
  char* addr = inet_ntoa(in);   
                 
  printf("%s\n", addr);
  return 0;
}

你可能感兴趣的:(Linux,网络基础,服务器,网络,运维)