UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

一、引入

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

二、两个函数的特点

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

三、struct 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 */
}

成员

  • h_name:主机的规范名称

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

  • h_aliases:主机的别名列表(指针数组,每个元素以'\0'结尾)
  • h_addrtype:主机的地址类型(例如:AF_INET等)
  • h_length:地址长度
  • h_addr_list:IP值,一个主机名可能对应于多个IP地址,所以这是个IP列表

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

四、gethostbyname

#include <netdb.h>
extern int h_errno;
struct hostent *gethostbyname(const char *name);

//返回值:成功返回struct hostent结构体指针;出错返回NULL且设置h_errno
  • 功能:通过给定的主机名返回hostent类型的结构
  • 此函数执行的是对A记录的查询,只能返回IPV4地址
  • 参数的注意事项:

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

  • 出错返回

 UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

  • hstrerror函数

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

  • 演示案例
#include<stdio.h>
#include<stdlib.h>
#include<netdb.h>
#include<arpa/inet.h>

int main(int argc, char **argv)
{
	char			*ptr, **pptr;
	char			str[INET_ADDRSTRLEN];
	struct hostent	*hptr;

	while (--argc > 0) {
		ptr = *++argv;
		if ( (hptr = gethostbyname(ptr)) == NULL) {
			printf("gethostbyname error for host: %s: %s\n",ptr, hstrerror(h_errno));
			continue;
		}
		printf("official hostname: %s\n", hptr->h_name);

		for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
			printf("\talias: %s\n", *pptr);

		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, *pptr, str, sizeof(str)));
			break;
		default:
			perror("unknown address type");
			break;
		}
	}
	exit(0);
}

 UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

  • 测试一个不存在的地址

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

五、gethostbyaddr

#include <netdb.h>
#include <sys/socket.h> /* for AF_INET */
struct hostent *gethostbyaddr(const void *addr,socklen_t len, int type);

//返回值:成功返回struct hostent结构体指针;出错返回NULL且设置h_errno

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

演示案例

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

int main(int argc, char **argv)
{
    char			*ptr, **pptr;
    char			str[INET_ADDRSTRLEN];
    struct hostent	*hptr;
    u_int addr;

    if (argc != 2)
    {
        printf("usage: %s IP-address\n",argv[0]);
        exit(EXIT_FAILURE);
    }
    if ((int) (addr = inet_addr (argv[1])) == -1) 
    {
        printf("IP-address must be of the form a.b.c.d\n");
        exit (EXIT_FAILURE);
    }
    
    while (--argc > 0) {
        ptr = *++argv;
        if ( (hptr = gethostbyaddr((char *) &addr, sizeof (addr), AF_INET)) == NULL) {
            printf("gethostbyname error for host: %s: %s\n",ptr, hstrerror(h_errno));
            continue;
        }
        printf("official hostname: %s\n", hptr->h_name);

        for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
            printf("\talias: %s\n", *pptr);

        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, *pptr, str,sizeof(str)));
            break;
        default:
            perror("unknown address type");
            break;
        }
    }
    exit(0);
}

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)

UNIX(网络编程-基本用法):16---地址解析函数(gethostbyname、gethostbyaddr)