天天看点

gethostbyname(), gethostbyaddr()的man手册

  • 英文小册原文地址:​​beej.us/guide/bgnet…​​
  • 作者:Beej
  • 中文翻译地址:​​www.chanmufeng.com/posts/netwo…​​

根据主机名获取IP地址,或者相反。

函数原型

#include <sys/socket.h>
#include <netdb.h>

struct hostent *gethostbyname(const char *name); // DEPRECATED!
struct hostent *gethostbyaddr(const char *addr, int len, int type);      

说明

请注意:这两个函数已经由 getaddrinfo() 与 getnameinfo() 取而代之!实际上,gethostbyname() 无法在 IPv6 中正常运行。

这些函数可以转换 host name 与 IP addresse。例如:你可以用 ​

​gethostbyname()​

​​ 取得其 IP address,并储存在 ​

​struct in_addr​

​。

反之,如果你有一个 ​

​struct in_addr​

​​ 或 ​

​struct in6_addr​

​​,你可以用 ​

​gethostbyaddr()​

​​得到 hostname。​

​gethostbyaddr()​

​​与 IPv6 相容,但是你最好使用新的 ​

​getnameinfo()​

​ 代替它。

(如果你有一个点分十进制格式的IP地址,你想要查询它的 hostname,你在使用 ​

​getaddrinfo()​

​​ 时最好要搭配​

​AI_CANONNAME​

​ 标识)。

​gethostbyname()​

​​ 接收一个类似 "​​www.chanmufeng.com​​" 的字串,然后传回一个 ​

​struct hostent​

​,里面包含了超多的数据,包括了 IP address(其它的信息包括官方的 host name、一连串的别名、地址类型、地址长度、以及地址列表。这是个通用的资料结构,在特定的用途上使用起来也很方便)。

在​

​gethostbyaddr()​

​​代入一个 ​

​struct in_addr​

​​或 ​

​struct in6_addr​

​​,然后就会返回给你一个相对应的 host name(如果有的话),它的作用和 ​

​gethostbyname()​

​​正好相反。至于参数,​

​addr​

​​是一个 ​

​char*​

​​,你实际上想要用一个指向​

​struct in_addr​

​​ 的指针;​

​len​

​​应该被设置成 ​

​sizeof(struct in_addr)​

​​,而 ​

​type​

​​ 应为 ​

​AF_INET​

​。

所以这个 ​

​struct hostent​

​ 会返回什么呢?它有许多字段,包含 host 的相关数据。

字段 描述
char *h_name 主机的规范(official、canonical)名字
char **h_aliases 可以使用数组访问的别名列表,最后一个元素为NULL
int h_addrtype 结果的地址类型,出于我们的目的,它实际上应该是AF_INET。
int length 以字节为单位的地址长度,对于IP(版本4)地址为4。
char **h_addr_list 此主机的IP地址列表。虽然这是一个char**,但它实际上是一个伪装的structin_addr *s数组。最后一个数组元素为NULL。
h_addr h_addr_list[0]的常用别名。如果你只是想要此主机的任何旧IP地址(是的,它们可以有多个),请使用此字段。

返回值

例子

// THIS IS A DEPRECATED METHOD OF GETTING HOST NAMES
// use getaddrinfo() instead!

#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    int i;
    struct hostent *he;
    struct in_addr **addr_list;

    if (argc != 2) {
        fprintf(stderr,"usage: ghbn hostname\n");
        return 1;
    }

    if ((he = gethostbyname(argv[1])) == NULL) {  // get the host info
        herror("gethostbyname");
        return 2;
    }

    // print information about this host:
    printf("Official name is: %s\n", he->h_name);
    printf("    IP addresses: ");
    addr_list = (struct in_addr **)he->h_addr_list;
    for(i = 0; addr_list[i] != NULL; i++) {
        printf("%s ", inet_ntoa(*addr_list[i]));
    }
    printf("\n");

    return 0;
}      
// THIS HAS BEEN SUPERCEDED
// use getnameinfo() instead!

struct hostent *he;
struct in_addr ipv4addr;
struct in6_addr ipv6addr;

inet_pton(AF_INET, "192.0.2.34", &ipv4addr);
he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
printf("Host name: %s\n", he->h_name);

inet_pton(AF_INET6, "2001:db8:63b3:1::beef", &ipv6addr);
he = gethostbyaddr(&ipv6addr, sizeof ipv6addr, AF_INET6);
printf("Host name: %s\n", he->h_name);      

参见