Linux网络编程之利用gethostbyname和gethostbyaddr函数获取主机信息

一、 数据结构struct hostent

GNU C库的头文件netdb.h中关于struct hostent定义如下:

/* Description of data base entry for a single host.  */
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 from name server.  */
#ifdef __USE_MISC
# define	h_addr	h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};

char *h_name: The official name of the host,表示的是主机的规范名。
char **h_aliases: An array of alternative names for the host, terminated by a null pointer,表示的是主机的别名。
int h_addrtype: The type of address; always AF_INET or AF_INET6 at present,表示的是主机ip地址的类型。ipv4为AF_INET,ipv6为AF_INET6。
int h_length: The length of the address in bytes,表示的是主机ip地址的长度。
char **h_addr_list: An array of pointers to network addresses for the host (in network byte order), terminated by a null pointer,表示的是主机的ip地址,注意,这个是以网络字节序存储的。

二、 获取主机信息函数gethostbyname和gethostbyaddr

1、 struct hostent * gethostbyname (const char *name)
The gethostbyname function returns information about the host named name. If the lookup fails, it returns a null pointer.

2、 struct hostent * gethostbyaddr (const void *addr, socklen_t length, int format)
The gethostbyaddr function returns information about the host with Internet address addr. The parameter addr is not really a pointer to char – it can be a pointer to an IPv4 or an IPv6 address. The length argument is the size (in bytes) of the address at addr. format specifies the address format; for an IPv4 Internet address, specify a value of AF_INET; for an IPv6 Internet address, use AF_INET6.
If the lookup fails, gethostbyaddr returns a null pointer.

三、 获取主机信息实例

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    struct sockaddr_in addr;
    struct hostent *host = NULL;

    // 输入参数有误
    if (argc != 2) {
        printf("USAGE:\t%s IP Adress | Domain Name\n", argv[0]);
        return 1;
    }
    // 输入为IP地址
    inet_aton(argv[1], &addr.sin_addr);
    host = gethostbyaddr((void *) &addr.sin_addr, 4, AF_INET);

    // 输入为域名
    if (host == NULL) {
        host = gethostbyname(argv[1]);
    }

    // 输入信息不能解析
    if (host == NULL) {
        printf("Input Data Error !\n");
        return 1;
    }

    printf("Input Data:\t%s\n", argv[1]);
    printf("Official Name:\t%s\n", host->h_name);
    for (int i = 0; host->h_aliases[i]; i++) {
        printf("Alias List%d:\t%s\n", i, host->h_aliases[i]);
    }
    printf("Address Type:\t%s\n",
           host->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6");
    printf("Address Length:\t%d\n", host->h_length);
    for (int i = 0; host->h_addr_list[i]; i++) {
        printf("Address List%d:\t%s\n", i,
               inet_ntoa(*(struct in_addr *) host->h_addr_list[i]));
    }

    return 0;
}

运行结果如下:

[ycxie@fedora Workspace]$ gcc gethost.c -o gethost -Wall
[ycxie@fedora Workspace]$
[ycxie@fedora Workspace]$ ./gethost www.xieyincai.com
Input Data:     www.xieyincai.com
Official Name:  xieyincai.com
Alias List0:    www.xieyincai.com
Address Type:   AF_INET
Address Length: 4
Address List0:  107.180.58.57
[ycxie@fedora Workspace]$
[ycxie@fedora Workspace]$ ./gethost www.mit.edu
Input Data:     www.mit.edu
Official Name:  e9566.dscb.akamaiedge.net
Alias List0:    www.mit.edu
Alias List1:    www.mit.edu.edgekey.net
Address Type:   AF_INET
Address Length: 4
Address List0:  23.220.180.92
[ycxie@fedora Workspace]$
[ycxie@fedora Workspace]$ ./gethost www.gov.cn
Input Data:     www.gov.cn
Official Name:  uz91.v.qingcdn.com
Alias List0:    www.gov.cn
Alias List1:    www.gov.cn.qingcdn.com
Address Type:   AF_INET
Address Length: 4
Address List0:  124.239.161.141
Address List1:  124.239.161.142
Address List2:  124.239.161.145
Address List3:  124.239.161.146
Address List4:  124.239.161.144
Address List5:  124.239.161.139
Address List6:  124.239.161.140
Address List7:  124.239.161.143
[ycxie@fedora Workspace]$
[ycxie@fedora Workspace]$ ./gethost 8.8.8.8
Input Data:     8.8.8.8
Official Name:  google-public-dns-a.google.com
Address Type:   AF_INET
Address Length: 4
Address List0:  8.8.8.8

Leave a Reply

Your email address will not be published. Required fields are marked *