gethostbyname()函数详解


基本概念:

gethostbyname()函数主要作用:用域名或者主机名获取地址,操作系统提供的库函数。以下的讨论基于linux环境


域名系统(Domain Name System, DNS)主要用于主机名字与IP地址之间的映射。每个组织机构往往运行一个或多个名字服务器(name server),我们编写的客户端和服务器等应用程序通过调用解析器(resolver)的函数库中的函数接触DNS服务器。常见的解析器函数是gethostbyname和gethostbyaddr,图11-1展示了应用进程、解析器和名字服务器之间的一个典型关系。

gethostbyname()函数详解_第1张图片


函数原型:

GETHOSTBYNAME(3)           Linux Programmer's Manual          GETHOSTBYNAME(3)

NAME
       gethostbyname,   gethostbyaddr,   sethostent,  gethostent,  endhostent,
       h_errno, herror, hstrerror, gethostbyaddr_r, gethostbyname2, gethostby‐
       name2_r, gethostbyname_r, gethostent_r - get network host entry

SYNOPSIS
       #include 
       extern int h_errno;

       struct hostent *gethostbyname(const char *name);

       #include        /* for AF_INET */

       const char *hstrerror(int err);

返回值:

失败返回NULL指针


成功返回的非空指针指向如下的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 */
}
gethostbyname()函数详解_第2张图片
hostent->h_name
表示的是主机的规范名。例如www.baidu.com的规范名其实是www.a.shifen.com。
    
hostent->h_aliases
表示的是主机的别名。www.baidu.com就是baidu他自己的别名。

hostent->h_addrtype    
表示的是主机ip地址的类型。只会是ipv4(AF_INET), 这个函数处理不了ipv6

hostent->h_length      
表示的是主机ip地址的长度。

hostent->h_addr_list
表示的是主机的ip地址。是网络字节序,需要通过inet_ntop函数转换。


测试代码 gethostbyname.cpp:

#include 
#include 
#include 
#include 

extern int h_errno;

int main(int argc, char **argv)
{
    if (argc != 2) {
        printf("Use example: %s www.google.com\n", *argv);
        return -1;
    }

    char *name = argv[1];
    struct hostent *hptr;

    hptr = gethostbyname(name);
    if (hptr == NULL) {
        printf("gethostbyname error for host: %s: %s\n", name, hstrerror(h_errno));
        return -1;
    }
    //输出主机的规范名
    printf("\tofficial: %s\n", hptr->h_name);

    //输出主机的别名
    char **pptr;
    char str[INET_ADDRSTRLEN];
    for (pptr=hptr->h_aliases; *pptr!=NULL; pptr++) {
        printf("\ttalias: %s\n", *pptr);
    }

    //输出ip地址
    switch (hptr->h_addrtype) {
        case AF_INET:
            pptr = hptr->h_addr_list;
            for (; *pptr!=NULL; pptr++) {
                printf("\taddress: %s\n",
                        inet_ntop(hptr->h_addrtype, hptr->h_addr, str, sizeof(str)));
            }
            break;
        default:
            printf("unknown address type\n");
            break;
    }

    return 0;
}


编译:

g++ gethostbyname.cpp


运行:

gethostbyname()函数详解_第3张图片


与nslookup对比:

gethostbyname()函数详解_第4张图片


ps: gethostname可能存在性能瓶颈问题,请参考文章:http://blog.csdn.net/shijun_zhang/article/details/6577426


参考:《unix网络编程》·卷1



你可能感兴趣的:(网络编程,linux,socket,tcp,udp,TCP/IP,UDP,TCP/IP)