数据结构--hostent

来源:互联网 发布:淘宝售假扣24分影响 编辑:程序博客网 时间:2024/06/02 18:47
hostent是host entry的缩写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表。之所以主机的地址是一个列表的形式,原因是当一个主机有多个网络接口时,自然有多个地址。

hostent定义

struct hostent {
    char *h_name;
   char **h_aliases;
   int h_addrtype;
   int h_length;
   char **h_addr_list;
   #define h_addr h_addr_list[0]
};

详细说明

h_name – 地址的正式名称。
h_aliases – 空字节-地址的预备名称的指针。
h_addrtype –地址类型; 通常是AF_INET。
h_length – 地址的比特长度。
h_addr_list – 零字节-主机网络地址指针。网络字节顺序。
h_addr - h_addr_list中的第一地址。

Examples

gethostbyname()成功时返回一个指向结构体 hostent 的指针,或者是个空(NULL)指针。(但是和以前不同,不设置errno,h_errno 设置错误信息。请看下面的herror()。但是如何使用呢?这个函数可不像它看上去那么难用。这里是个例子:
一、
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct hostent *h;
if (argc !=2) { /*检查命令行*/fprintf(stderr,"usage:getip address");
exit(1);
}
if ((h=gethostbyname(argv[1])) == NULL) {/*取得地址信息/herror("gethostbyname");
exit(1);
}
printf("host name :%s", h->h_name);
printf("IP Address :%s",inet_ntoa(*((struct in_addr *)h->h_addr)));
return 0;
}
在使用 gethostbyname() 的时候,你不能用perror() 打印错误信息 (因为 errno 没有使用),你应该调用herror()。
相当简单,你只是传递一个保存机器名的字符串 给gethostbyname(),然后从返回的数据结构 struct hostent 中获取信息。唯一也许让人不解的是输出 IP 地址信息。h->h_addr 是一个 char *, 但是 inet_ntoa() 需要的是 structin_addr。因此,我转换 h->h_addr 成 struct in_addr *,然后得到数据。
比如“192.168.001.001”,(默认是第一块网卡的地址)
实际储存的情况是这样的;
hostent->h_addr_list[0][0]= -64
hostent->h_addr_list[0][1]= -88
hostent->h_addr_list[0][2]= 1
hostent->h_addr_list[0][3]= 1
那么它是这么转的吗?
int         i;
char       buff[]="192.168.001.001";
int         value[4]={0};
for(i=0;i<4;i++)
{
value[i]=(buff[4*i]-48)×100+(buff[4*i+1]-48)×10+(buff[4*i+2]-48);
}
//比如:value[1]=(49-48)×100+(57-48)×10+(50-48)×2=192
for(i=0;i<4;i++)
{
if(value[i]>127)
{
hostent->h_addr[0][i]     =     value[i]-256;
}
else
{
hostent->h_addr_list[0][i]      =     value[i];
}
}
在引用的时候可以看下面代码:
char *ip;
PHOSTENT hostinfo;
ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
printf("%s\n",ip);
或者
for(j=0;j<h_length;j++)
{
CString addr;
if(j>0)
str+=".";
sddr.Format("%u",(unsigned int)((unsigned char*)phost->h_addr_list[occurred])[j]);
str+=addr;
}
二、
#include  <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "wininet.lib")
int main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
DWORD dwError;
int i = 0;
struct hostent *remoteHost;
char *host_name;
struct in_addr addr;
char **pAlias;
// Validate the parameters
if (argc != 2) {
printf("usage: %s ipv4address\n", argv[0]);
printf(" or\n");
printf("       %s hostname\n", argv[0]);
printf("  to return the host\n");
printf("       %s 127.0.0.1\n", argv[0]);
printf("  to return the IP addresses for a host\n");
printf("       %s 网址地址域名\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
host_name = argv[1];
// If the user input is an alpha name for the host, use gethostbyname()
// If not, get host by addr (assume IPv4)
if (isalpha(host_name[0])) {        /* host address is a name */
printf("Calling gethostbyname with %s\n", host_name);
remoteHost = gethostbyname(host_name);
} else {
printf("Calling gethostbyaddr with %s\n", host_name);
addr.s_addr = inet_addr(host_name);
if (addr.s_addr == INADDR_NONE) {
printf("The IPv4 address entered must be a legal address\n");
return 1;
} else
remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
}
if (remoteHost == NULL) {
dwError = WSAGetLastError();
if (dwError != 0) {
if (dwError == WSAHOST_NOT_FOUND) {
printf("Host not found\n");
return 1;
} else if (dwError == WSANO_DATA) {
printf("No data record found\n");
return 1;
} else {
printf("Function failed with error: %ld\n", dwError);
return 1;
}
}
} else {
printf("Function returned:\n");
printf("\tOfficial name: %s\n", remoteHost->h_name);
for (pAlias = remoteHost->h_aliases; *pAlias != 0; pAlias++) {
printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
}
printf("\tAddress type: ");
switch (remoteHost->h_addrtype) {
case AF_INET:
printf("AF_INET\n");
break;
case AF_INET6:
printf("AF_INET6\n");
break;
case AF_NETBIOS:
printf("AF_NETBIOS\n");
break;
default:
printf(" %d\n", remoteHost->h_addrtype);
break;
}
printf("\tAddress length: %d\n", remoteHost->h_length);
if (remoteHost->h_addrtype == AF_INET) {
while (remoteHost->h_addr_list[i] != 0) {
addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
printf("\tIPv4 Address #%d: %s\n", i, inet_ntoa(addr));
}
} else if (remoteHost->h_addrtype == AF_INET6)
printf("\tRemotehost is an IPv6 address\n");
}
return 0;
}
原创粉丝点击