gethostbyaddr 宏 (wsipv6ok.h)

[从 Windows 套接字 2 开始,不再建议使用 gethostbyaddr 。 请改用 getnameinfo。]

gethostbyaddr 函数检索与网络地址对应的主机信息。

语法

void gethostbyaddr(
  [in]  a,
  [in]  b,
  [in]  c
);

参数

[in] a

指向按网络字节顺序表示的地址的指针。

[in] b

地址的长度(以字节为单位)。

[in] c

地址类型,例如AF_INET地址系列类型 (TCP、UDP 和其他关联的 Internet 协议) 。 地址系列的可能值在 Winsock2.h 头文件中定义。

在针对 Windows Vista 及更高版本发布的 Windows SDK 上,头文件的组织方式已更改,地址系列的可能值在 Ws2def.h 头文件中定义。 请注意,Ws2def.h 头文件会自动包含在 Winsock2.h 中,永远不应直接使用。

请注意,AF_地址系列和PF_协议系列常量的值 (相同,例如 ,AF_INETPF_INET) ,因此可以使用任一常量。

下表列出了支持的地址系列的可能值。

Value 含义
AF_INET
2
Internet 协议版本 4 (IPv4) 地址系列。
AF_NETBIOS
17
NetBIOS 地址系列。 仅当安装了适用于 NetBIOS 的 Windows 套接字提供程序时,才支持此地址系列。
AF_INET6
23
Internet 协议版本 6 (IPv6) 地址系列。

返回值

备注

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

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

应用程序不应尝试释放返回的 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
标头 wsipv6ok.h (包括 Winsock2.h、Winsock.h)
Library Ws2_32.lib
DLL Ws2_32.dll

另请参阅

GetAddrInfoEx

GetAddrInfoW

WSAAsyncGetHostByAddr

Winsock 函数

Winsock 参考

addrinfo

addrinfoW

getaddrinfo

gethostbyname

hostent