天天看點

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);      

參見