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 来检索特定的错误代码。

错误代码 含义
WSANOTINITIALISED
在使用此函数之前,必须成功调用 WSAStartup
WSAEINVAL
提供的参数无效。 如果在类型参数中指定了AF_INET6,并且 len 参数未设置为等于 IPv6 地址的大小,则返回此错误。
WSAENETDOWN
网络子系统失败。
WSAHOST_NOT_FOUND
找不到权威应答主机。
WSATRY_AGAIN
找不到非授权主机,或服务器失败。
WSANO_RECOVERY
发生不可恢复的错误。
WSANO_DATA
有效名称,没有请求类型的数据记录。
WSAEINPROGRESS
阻止 Windows Sockets 1.1 调用正在进行,或者服务提供程序仍在处理回调函数。
WSAEAFNOSUPPORT
Windows 套接字实现不支持指定的 类型
WSAEFAULT
addr 参数不是用户地址空间的有效部分,或者 len 参数太小。
WSAEINTR
阻止的 Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。

注解

gethostbyaddr 函数返回指向 hostent 结构的指针,该结构包含与给定网络地址对应的名称和地址。

gethostbyaddr 函数返回的 hostent 结构的内存由 Winsock DLL 从线程本地存储内部分配。 无论在线程上调用 gethostbyaddrgethostbyname 函数多少次,都只分配和使用一个 hostent 结构。 如果要在同一线程上对 gethostbyaddrgethostbyname 函数进行其他调用,则必须将返回的 hostent 结构复制到应用程序缓冲区。 否则,返回值将被同一线程上的后续 gethostbyaddrgethostbyname 调用覆盖。 为返回的 主机 结构分配的内部内存在线程退出时由 Winsock DLL 释放。

应用程序不应尝试释放返回的 hostent 结构使用的内存。 应用程序不得尝试修改此结构或释放其任何组件。 此外,每个线程只分配此结构的一个副本,因此应用程序应在向 gethostbyaddrgethostbyname 发出任何其他函数调用之前复制它所需的任何信息。

虽然从 Windows 套接字 2 开始不再建议使用 gethostbyaddr ,并且应使用 getnameinfo 函数, 但 gethostbyaddr 能够返回 NetBIOS 名称; getnameinfo 不是。 需要 NetBIOS 名称解析的开发人员可能需要使用 gethostbyaddr ,直到其应用程序完全独立于 NetBIOS 名称。

注意 使用 gethostbyaddr 函数执行反向查找的功能很方便,但此类查找本质上被视为不可靠,应仅用作提示。
 

示例代码

以下示例演示如何使用 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.1Windows 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

另请参阅

GetAddrInfoEx

GetAddrInfoW

WSAAsyncGetHostByAddr

Winsock 函数

Winsock 参考

addrinfo

addrinfoW

getaddrinfo

gethostbyname

hostent