gethostbyaddr 函数 (winsock.h)
[从 Windows 套接字 2 开始,不再建议使用 gethostbyaddr 。 请改用 getnameinfo。]
gethostbyaddr 函数检索对应于网络地址的主机信息。
语法
hostent * gethostbyaddr(
const char *addr,
int len,
int type
);
参数
addr
TBD
len
TBD
type
TBD
返回值
如果未发生错误, gethostbyaddr 将返回指向 hostent 结构的指针。 否则,它将返回一个 null 指针,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
错误代码 | 含义 |
---|---|
在使用此函数之前,必须成功调用 WSAStartup 。 | |
提供的参数无效。 如果在类型参数中指定了AF_INET6,并且 len 参数未设置为等于 IPv6 地址的大小,则返回此错误。 | |
网络子系统失败。 | |
找不到权威应答主机。 | |
找不到非授权主机,或服务器失败。 | |
发生不可恢复的错误。 | |
有效名称,没有请求类型的数据记录。 | |
阻止 Windows Sockets 1.1 调用正在进行,或者服务提供程序仍在处理回调函数。 | |
Windows 套接字实现不支持指定的 类型 。 | |
addr 参数不是用户地址空间的有效部分,或者 len 参数太小。 | |
阻止的 Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。 |
注解
gethostbyaddr 函数返回指向 hostent 结构的指针,该结构包含与给定网络地址对应的名称和地址。
gethostbyaddr 函数返回的 hostent 结构的内存由 Winsock DLL 从线程本地存储内部分配。 无论在线程上调用 gethostbyaddr 或 gethostbyname 函数多少次,都只分配和使用一个 hostent 结构。 如果要在同一线程上对 gethostbyaddr 或 gethostbyname 函数进行其他调用,则必须将返回的 hostent 结构复制到应用程序缓冲区。 否则,返回值将被同一线程上的后续 gethostbyaddr 或 gethostbyname 调用覆盖。 为返回的 主机 结构分配的内部内存在线程退出时由 Winsock DLL 释放。
应用程序不应尝试释放返回的 hostent 结构使用的内存。 应用程序不得尝试修改此结构或释放其任何组件。 此外,每个线程只分配此结构的一个副本,因此应用程序应在向 gethostbyaddr 或 gethostbyname 发出任何其他函数调用之前复制它所需的任何信息。
虽然从 Windows 套接字 2 开始不再建议使用 gethostbyaddr ,并且应使用 getnameinfo 函数, 但 gethostbyaddr 能够返回 NetBIOS 名称; getnameinfo 不是。 需要 NetBIOS 名称解析的开发人员可能需要使用 gethostbyaddr ,直到其应用程序完全独立于 NetBIOS 名称。
示例代码
以下示例演示如何使用 gethostbyaddr 函数。#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
int main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
DWORD dwError;
int i = 0;
int bIpv6 = 0;
struct hostent *remoteHost;
char *host_addr;
struct in_addr addr = { 0 };
IN6_ADDR addr6;
char **pAlias;
// Validate the parameters
if (argc < 2) {
printf("usage: %s 4 ipv4address\n", argv[0]);
printf(" or\n");
printf("usage: %s 6 ipv6address\n", argv[0]);
printf(" to return the hostname\n");
printf(" %s 4 127.0.0.1\n", argv[0]);
printf(" %s 6 0::1\n", argv[0]);
return 1;
}
// Validate parameters
if (atoi(argv[1]) == 4)
bIpv6 = 0;
else if (atoi(argv[1]) == 6)
bIpv6 = 1;
else {
printf("usage: %s 4 ipv4address\n", argv[0]);
printf(" or\n");
printf("usage: %s 6 ipv6address\n", argv[0]);
printf(" to return the hostname\n");
printf(" %s 4 127.0.0.1\n", argv[0]);
printf(" %s 6 0::1\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_addr = argv[2];
printf("Calling gethostbyaddr with %s\n", host_addr);
if (bIpv6 == 1) {
{
iResult = inet_pton(AF_INET6, host_addr, &addr6);
if (iResult == 0) {
printf("The IPv6 address entered must be a legal address\n");
return 1;
} else
remoteHost = gethostbyaddr((char *) &addr6, 16, AF_INET6);
}
} else {
addr.s_addr = inet_addr(host_addr);
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;
}
Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。
Windows 8.1和Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 8.1、Windows Vista [桌面应用 |UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | winsock.h (包括 Winsock2.h、Winsock.h) |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |