使用這個東西,首先要包含2個頭文件:
#include <netdb.h>
#include <sys/socket.h>
struct hostent *gethostbyname(const char *name);
這個函數(shù)的傳入值是域名或者主機名,例如"
www.google.com","wpc
"等等。
傳出值,是一個hostent的結(jié)構(gòu)(如下)。如果函數(shù)調(diào)用失敗,將返回NULL。
struct hostent {
? char? *h_name;
? char? **h_aliases;
? int?? h_addrtype;
? int?? h_length;
? char? **h_addr_list;
? };
解釋一下這個結(jié)構(gòu):
其中,
? char *h_name 表示的是主機的規(guī)范名。例如
www.google.com
的規(guī)范名其實是
www.l.google.com
。
? char?? **h_aliases 表示的是主機的別名。
www.google.com
就是google他自己的別名。有的時候,有的主機可能有好幾個別名,這些,其實都是為了易于用戶記憶而為自己的網(wǎng)站多取的名字。
? int?? h_addrtype 表示的是主機ip地址的類型,到底是ipv4(AF_INET),還是ipv6(AF_INET6)
? int?? h_length 表示的是主機ip地址的長度
? int?? **h_addr_lisst 表示的是主機的ip地址,注意,這個是以網(wǎng)絡(luò)字節(jié)序存儲的。千萬不要直接用printf帶%s參數(shù)來打這個東西,會有問題的哇。所以到真正需要打印出這個IP的話,需要調(diào)用inet_ntop()。
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
這個函數(shù),是將類型為af的網(wǎng)絡(luò)地址結(jié)構(gòu)src,轉(zhuǎn)換成主機序的字符串形式,存放在長度為cnt的字符串中。
這個函數(shù),其實就是返回指向dst的一個指針。如果函數(shù)調(diào)用錯誤,返回值是NULL。
?
下面是例程,有詳細(xì)的注釋。
#include <netdb.h>
#include <sys/socket.h>
int main(int argc, char **argv)
{
?char *ptr,**pptr;
?struct hostent *hptr;
?char str[32];
?/* 取得命令后第一個參數(shù),即要解析的域名或主機名 */
?ptr = argv[1];
?/* 調(diào)用gethostbyname()。調(diào)用結(jié)果都存在hptr中 */
?if( (hptr = gethostbyname(ptr) ) == NULL )
?{
??printf("gethostbyname error for host:%s\n", ptr);
??return 0; /* 如果調(diào)用gethostbyname發(fā)生錯誤,返回1 */
?}
?/* 將主機的規(guī)范名打出來 */
?printf("official hostname:%s\n",hptr->h_name);
?/* 主機可能有多個別名,將所有別名分別打出來 */
?for(pptr = hptr->h_aliases; *pptr != NULL; pptr++)
??printf("? alias:%s\n",*pptr);
?/* 根據(jù)地址類型,將地址打出來 */
?switch(hptr->h_addrtype)
?{
??case AF_INET:
??case AF_INET6:
???pptr=hptr->h_addr_list;
???/* 將剛才得到的所有地址都打出來。其中調(diào)用了inet_ntop()函數(shù) */
???for(;*pptr!=NULL;pptr++)
????printf("? address:%s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
???break;
??default:
???printf("unknown address type\n");
???break;
?}
?return 0;
}