Winsock网络编程获取主机信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hou09tian/article/details/83537826

在Winsock网络编程中,可以通过主机的IP地址获取主机信息;也可以通过主机名获取主机信息。

1 通过主机IP地址获取主机信息

gethostbyaddr()函数和getnameinfo()函数可以通过主机IP地址获取主机信息。

1.1 gethostbyaddr()函数

该函数的作用是根据网络地址获取主机信息。

1.1.1 函数格式

该函数的格式为

struct hostent* FAR gethostbyaddr(

  __in const char* addr,

  __in int Len,

  __in int type

);

其中,参数addr是主机IP地址;Len是IP地址的长度,单位是字节;type表示地址的类型,该参数的取值可以是AF_INET、AF_INET6和AF_NETBIOS,分别表示IPv4、IPv6和NetBIOS。

如果成功获取了主机信息,则gethostbyaddr()函数返回一个hostent结构的指针,如果失败,则返回一个指向NULL的指针。

1.1.2 hostent结构

hostent结构用来存储主机信息,包括主机名、IPv4地址等。该结构的格式为

typedef struct hostent{

  char FAR* h_name;

  char FAR h_aliases;

  short h_addrtype;

  short h_length;

  char FAR FAR** h_addr_list;

}HOSTENT, *PHOSTENT, FAR* LPHOSTENT;

其中,成员变量h_name表示主机官方的名字;h_aliases表示主机的别名;h_addrtype返回地址的类型;h_length表示每个地址的长度,单位是字节;h_addr_list主机地址的列表。

1.1.3 相关代码

使用gethostbyaddr()函数和hostent结构获取主机信息的代码如下所示

in_addr addr;

addr.s_addr = inet_addr(“192.168.1.1”);

hostent* info_host = gethostbyaddr((char*)&addr, 4, AF_INET);

需要注意的是,gethostbyaddr()函数的第一个参数不是简单的IP地址字符串,而是将IP地址转换为整形后,再将整形看成字符串。

此时,主机的名字就保存再info_host->h_name中。

1.2 getnameinfo()函数

该函数的作用是将IP地址转换成主机名,并且还可以将端口号转换为服务名。

1.2.1 函数格式

该函数的格式为

int WSAAPI getnameinfo(

  __in const struct sockaddr FAR* sa,

  __in socklen_t saLen,

  __out char FAR* host,

  __in DWORD hostLen,

  __out char FAR* serv,

  __in DWORD servLen,

  __in int flags

);

其中,sa是一个指向sockaddr的指针,该指针指向的内容包含了IP地址和端口号;saLen是参数sa的大小,单位是比特;host是转换后的主机名的指针;hostLen指定了参数host的大小,单位是比特;serv是指向转换后的服务名的指针;servLen是参数serv的大小,单位是比特;flags指定了转换的方式。

1.2.2 相关代码

使用getnameinfo()函数获取主机名的相关代码如下所示

char hostname[NI_MAXHOST];

char servInfo[NI_MAXSERV];

struct sockaddr_in saGNI;

saGNI.sin_family = AF_INET;

saGNI.sin_addr.s_addr = inet_addr(“192.168.1.1”);

saGNI.sin_port = htons(80);

getnameinfo(

(struct sockaddr*)&saGNI

, sizeof(struct sockaddr)

, hostname

, NI_MAXHOST

, servInfo

, NI_MAXSERV

, NI_NUMERICSERV

);

其中,NI_MAXHOST和NI_MAXSERV是在WS2tcpip.h中定义的常量,分别表示主机名的最大值和服务名的最大值,其值分别是1025和32。根据IP地址获取到的主机名保存在hostname中,根据端口获取到的服务名保存在servInfo中。NI_NUMERICSERV表示获取到的服务名用端口号代替,如果无法获取到主机名,则用该主机的IP地址代替。

2 通过主机名获取主机信息

gethostbyname()函数和getaddrinfo()函数可以通过主机名获取主机信息。

2.1 gethostbyname()函数

2.1.1 函数格式

gethostbyname()函数的格式为

struct hostent* FAR gethostbyname(

  __in const char* name

);

其中,参数name表示主机名。函数的返回值是hostent结构的指针。

2.1.2 相关代码

hostent* info_host = gethostbyaddr(“myhost”);

获取到的主机信息保存在info_host所指向的内存地址中。

2.2 getaddrinfo()函数

2.2.1 函数格式

getaddrinfo()函数的格式为:

INT WSAAPI getaddrinfo(

 PCSTR pNodeName

, PCSTR pServiceName

, const ADDRINFOA *pHints

, PADDRINFOA *ppResult

);

其中,参数pNodeName是主机名;pServiceName是服务名或者服务对应的端口号;pHints是addrinfo结构的指针,用来提供支持的套接字类型的一些提示;ppResult是一个指针,该指针指向一个或多个addrinfo结构的链表,这些addrinfo结构包含了要获取的主机信息。如果成功获取了主机信息,则getaddrinfo()函数的返回值是0,否则是非零。

2.2.2 addrinfo结构

该结构用在getaddrinfo()函数中保存主机地址信息,其格式为

typedef struct addrinfo {

  int             ai_flags;

  int             ai_family;

  int             ai_socktype;

  int             ai_protocol;

  size_t          ai_addrlen;

  char            *ai_canonname;

  struct sockaddr  *ai_addr;

  struct addrinfo  *ai_next;

} ADDRINFOA, *PADDRINFOA;

其中,ai_flags指定了用在getaddrinfo()函数中的选项;ai_family是地址族;ai_socktype是套接字的类型;ai_protocol是协议类型;ai_addrlen指定了ai_addr指向的内存的大小;ai_canonname指定了主机的正规名字;ai_addr是sockaddr结构的指针,该指针指向的内容为获取到的主机信息;ai_next是一个addrinfo结构的指针,该指针指向的是链表中下一个addrinfo。

2.2.3 相关代码

struct addrinfo hints;

ZeroMemory( &hints, sizeof(hints) );

hints.ai_family = AF_UNSPEC;

hints.ai_socktype = SOCK_STREAM;

hints.ai_protocol = IPPROTO_TCP;

struct addrinfo *result = NULL;

getaddrinfo(“myHost”, NULL, &hints, &result);

获取到主机信息保存在result中。

猜你喜欢

转载自blog.csdn.net/hou09tian/article/details/83537826