在C语言SOCKET编程中,往往需要通过 主机名/域名 来求得IP地址。比例说,我们想连接上百度服务器,但是不可能人工先去查它的IP,然后在写进代码里。万一IP变了呢,那代码不是要重写?所以,这一章,主要介绍如何通过主机名/域名来求服务器IP地址。
首先认识一个表示主机信息的结构体:
1 2 3 4 5 6 7 8 |
struct hostent{ char* h_name; //主机的正式名称 char** h_aliases: //主机的备用名称表 int h_addrtype; //地址类型, 比如"AF_INET" int h_length; //地址长度,大家目前使用的都是32位 char** h_addr_list; //主机地址表 #define h_addr h_addr_list[0]; //主机地址表中的首个地址 } |
h_addrtype 这是表示主机所使用的地址类型的定义,在C语言winsock2.h头文件中以“AF_”开头的宏定义就是它的值。如果使用的是IPV4,则值为”AF_INET”,如果是IPV6,值为“AF_INET4”。
h_length 地址的长度,一般都用IPV4中,所以都是32位/4字节。
h_addr_list 在一个主机名中,往往有很多对应的IP地址。当我们通过使用主机名查IP时,就会把返回的所有IP地址保存在主机地址表中。我们一般使用h_addr来取得第一个地址就行了。
在C语言的SOCKET网络编程中,我们使用gethostbyname()函数来获取主机信息,它的函数原型如下:
struct hostent* gethostbyname(const char* hostname );
hostname是个包含主机名/域名的字符串,函数通过给定的主机名,返回一个包含主机名称和主机地址信息的指针结构体。
如果我们想要返回百度服务器的主机信息,则:
char baidu_hostname[]="www.baidu.com"
struct hostent* baidu_hostent;
baidu_hostent = gethostbyname( baidu_hostname );
取得IP地址后,使用下面方法把IP地址打印到标准输出上:
struct in_addr baidu_addr;
baidu_addr.s_addr = *(unsigned long * ) baidu_hostent->h_addr;
printf("baidu_IPV4 : %s " , inet_ntoa( baidu_addr ) );
in_addr 是一个用来表示32位IPV4网络地址的结构体,s_addr是个使用unsigned long数据格式来表示一个IPV4 地址的结构成员。
inet_ntoa() 将指定的网络地址转换成 以点隔字符串表示的IPV4地址,例如“192.168.1.101”就是个点隔字符串网络地址。
//函数原型
char* inet_ntoa( struct in_addr);
通过以上方法,以后就可以直接使用主机名/域名来获取IPV4地址,而再不用人工去查找。
下面是关于本期讲解内容的总结的源代码:
#include
#include
//通过改变以下宏定义来修改要解析的主机名
#define HOSTNAME "www.dingguofeng.com"
int main( int argc , char* argv[])
{
int ret;
struct hostent *host;
struct in_addr addr;
//启动socket服务
WSADATA wsaData;
ret = WSAStartup( 0x101 , &wsaData);
//如果启动成功 ,返回值为0
if( ret != 0 )
{
printf("WSAStartup error:%d " , WSAGetLastError() );
return 1;
}
//获取主机信息
host = gethostbyname( HOSTNAME );
if( host == NULL )
{
printf("gethostbyname error:%d" , WSAGetLastError() );
return 1;
}
addr.s_addr = *(unsigned long * )host->h_addr;
printf("主机名 :%sn" , host->h_name);
printf("主机地址: %sn " , inet_ntoa( addr ) );
WSACleanup();
return 0;
}
发表评论
要发表评论,您必须先登录。