Unix网络编程之名字与地址转化—gethostbyname

在Unix网络编程中,有几个函数用来实现主机名与IP地址之间的转化,下面介绍gethostbyname

#include <netdb.h>

struct hostent *gethostbyname(const char *hostname)

参数说明:

hostname指向一个字符串,该字符串就是需要查找host信息的主机名

返回值说明:

成功返回一个非空指针,出错返回NULL,同时设置h_errno(比如参数是不准确的主机名就会导致调用失败)。如果函数调用成功的话,就会返回一个指向hostent结构体的指针,我们所需要的信息就在这个结构体里面,所有很有必要了解这个结构体

struct hostent{
      char * h_name;          //h_name表示所查询主机的规范名字
      char ** h_aliases;      //h_aliases表示所查询主机的别名的列表,因为别名可能有多个
      short h_addrtype;      //h_addrtype表示所查询主机的IP地址的类型,函数仅支持IPv4,这一项固定是AF_INET
      short h_length;          //h_length表示IP地址的长度,IPv4的长度都为4,这项也是固定的
      char ** h_addr_list;   //h_addr_list表示IP地址的列表,因为一个主机可能有多个IP地址

};


结构如下图所示:

实例代码:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char **argv)
{
    struct hostent *ht;
    char **alias;
    char **addr;
    char address[100];

    ht = gethostbyname(argv[1]);      //调用gethostbyname函数
  
    if(ht == NULL)                             //调用失败则直接返回
    {
        printf("error\n");

        return 0;

    }

    alias = ht->h_aliases;
    addr = ht->h_addr_list;

    printf("%s\n",ht->h_name);        //打印主机的规范名
   
    while(*alias != NULL)                //循环打印主机的别名,可能有多个,也可能没有
    {
        printf("anc\n");
        printf("size is %lu\n", strlen(*alias));
        printf("one of aliases is %s\n", *alias);
        *alias++;
    }

    printf("%d\n",ht->h_addrtype);  //打印IP地址的类型,固定值为AF_INET,代表的整型值为2
    printf("%d\n",ht->h_length);      //打印IP地址的长度,在IPv4中为4个字节

    while(*addr != NULL)                //循环打印主机的IP地址,可能有多个
    {
        memset(address, '\0', 100);
        inet_ntop(AF_INET, *addr, address, sizeof(address));
        printf("one of addr is %s\n", address);
        *addr++;
    }

    return 0;
}


gethostbyname的查询机制:

           gethostbyname函数首先会根据/etc/hosts文件来查找指定主机的IP地址,如果查找不到,那么就会转到DNS服务器去查找,注意我们的查找结果与DNS服务器有关,打个比方,如果一个主机有5个IP地址,但是某个DNS服务器只收录了其中的三个,那么当我们以该DNS服务器作为查找节点时,就只会返回这三个IP地址,不再往下递归查询。整个查询过程的递归的,一直到查找成功或者查找失败,注意查找成功表示找到一个记录就算成功,它并不会将所有的记录全部查找出来。


获取错误信息:

       如果gethostbyname函数调用失败,那么会设置全局变量h_errno的值(默认值为0,表示没有错误发生),我们可以根据这个值来打印错误信息。

      h_errno的取值如下:

   

    我们通过如下代码就可以得到错误信息:

    if(ht == NULL)                           
    {
        printf("error\n");

        printf("%s\n",hstrerror(h_errno));

        return 0;

    }

    函数hstrerror会根据全局变量h_errno的值去查找对应的错误信息,它返回一个char指针,指向错误信息字符串(字符串的内容就是上面表格罗列的四条,可能根据系统不同而有所变化)。


存在的问题:

    在我的实验过程中(实验环境是Ubuntu虚拟机),还存在一个问题,就是gethostbyname函数已经正常调用了,并且得到了正确的IP地址,然而全局变量h_errno会被设置HOST_NOT_FOUND,也就是说产生了Unknown host错误,这里还明白原因是什么,如果有了解的大神,希望能够解答一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值