在网络编程时,知道域名是不能直接访问一个主机的,需要转换成相应的IP地址。有时在程序中需要将一个IP地址转换成一个域名。本节将讲解C程序中的IP地址与域名的转换问题。
提示:在TCP/IP网络中,通信双方的主机必须知道彼此的IP地址方可进行正常的通信,如果给出的主机的域名,在开始正常的通信前必须把域名转换为IP地址。这个域名到IP地址的转换过程称为域名解析。
用域名取得主机的IP地址
用域名取得主机的IP地址:域名是为了便于记忆,来代替IP地址访问网络的方法。在使用域名访问网络时,需要将这个域名转换成相对应的IP地址。用域名返回地址的函数是gethostbyname。这个函数的使用方法如下所示。
01 struct hostent *gethostbyname(const char *name);
在参数列表中,name是一个表示域名的字符串。函数会把这个域名转换成一个主机地址结构体返回。结构体hostent的定义方法如下所示。
01 struct hostent
02 {
03 char *h_name;
04 char **h_aliases;
05 int h_addrtype;
06 int h_length;
07 char **h_addr_list;
08 }
这个结构体成员含义如下所示。
h_name:正式的主机名称。
h_aliases:这个主机的别名。
h_addrtype:主机名的类型。
h_length:地址的长度。
addr_list:从域名服务器取得的主机的地址。
在解析域名时,可能没有这个域名或域名服务器发生错误。可能返回的错误信息如下所示。可以用error来捕获错误编号。
HOST_NOT_FOUND:主机没有找到。
NO_ADDRESS or NO_DATA:没有IP地址或没有数据。
NO_RECOVERY:域名服务器发生错误。
TRY_AGAIN:请稍候再重试。
DEMO:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc,char **argv)
{
extern int h_errno;
struct hostent *h;
struct in_addr in;
struct sockaddr_in addr_in;
h=gethostbyname("xxx.xxx.com");
if(h==NULL)
{
printf("%s
",hstrerror(h_errno));
}
else
{
memcpy(&addr_in.sin_addr.s_addr,h->h_addr,4);
in.s_addr=addr_in.sin_addr.s_addr;
printf("host name:%s
",h->h_name);
printf("ip lenght:%d
",h->h_length);//IPv4 or IPv6
printf("type:%d
",h->h_addrtype);
printf("ip:%s
",inet_ntoa(in));//将一个IP转换成一个互联网标准点分格式的字符串
}
return 0;
}
用IP地址返回域名
用IP地址返回域名:用一个IP地址可以查询到这个IP的域名,需要使用的函数是gethostbyaddr。这个函数的使用方法如下所示。
01 struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);
在参数列表中,addr是一个保存了IP地址的字符串。len是这个IP地址的长度。type的值一般为AF_INET。函数的返回值是hostent类型的指针。这一指针的定义和上一节的相同。如果转换失败,则返回null指针。下面的实例,是用gethostbyaddr函数查找一个IP所对应的域名。其中使用的IP地址是央视国际的网站。
提示:把IP地址转换为域名的过程称为反向域名解析。