gethostbyaddr 巨集 (wsipv6ok.h)

[gethostbyaddr 不再建議用於 Windows Sockets 2。 請改用 getnameinfo。]

gethostbyaddr函式會擷取對應至網路位址的主機資訊。

語法

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

參數

[in] a

網路位元組順序中位址的指標。

[in] b

位址的長度,以位元組為單位。

[in] c

位址的類型,例如AF_INET位址系列類型 (與 TCP、UDP 和其他相關聯的網際網路通訊協定) 。 位址系列的可能值定義在 Winsock2.h 標頭檔中。

在針對 Windows Vista 和更新版本發行的 Windows SDK 上,標頭檔的組織已變更,且位址系列可能的值定義在 Ws2def.h 標頭檔中。 請注意,Ws2def.h 標頭檔會自動包含在 Winsock2.h 中,不應直接使用。

請注意,AF_位址系列和PF_通訊協定系列常數的值 (相同,例如, AF_INETPF_INET) ,因此可以使用任一個常數。

下表列出支援的位址系列可能值。

意義
AF_INET
2
網際網路通訊協定第 4 版 (IPv4) 位址系列。
AF_NETBIOS
17
NetBIOS 位址系列。 只有在已安裝 NetBIOS 的 Windows Sockets 提供者時,才支援此位址系列。
AF_INET6
23
網際網路通訊協定第 6 版 (IPv6) 位址系列。

傳回值

備註

gethostbyaddr函式會傳回hostent結構的指標,其中包含對應至指定網路位址的名稱和位址。

gethostbyaddr函式所傳回之hostent結構的記憶體是由 Winsock DLL 從執行緒本機儲存體內部配置。 不論執行緒上呼叫gethostbyaddrgethostbyname函式的次數,都只會配置及使用單一hostent結構。 如果要對相同執行緒上的gethostbyaddrgethostbyname函式進行其他呼叫,則必須將傳回的hostent結構複製到應用程式緩衝區。 否則,傳回值將會由相同執行緒上的後續 gethostbyaddrgethostbyname 呼叫覆寫。 當執行緒結束時,Winsock DLL 會釋放配置給傳回 之 hostent 結構的內部記憶體。

應用程式不應該嘗試釋放傳回 的 hostent 結構所使用的記憶體。 應用程式絕對不能嘗試修改此結構,或釋放其任何元件。 此外,每個執行緒只會配置此結構的一個複本,因此應用程式應該先複製它所需的任何資訊,再發出任何其他函式呼叫 gethostbyaddrgethostbyname

雖然 不再建議使用 gethostbyaddr 作為 Windows Sockets 2,而且應該使用 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 市集應用程式支援此功能,Windows 8.1、Windows Server 2012 R2 及更新版本。

規格需求

   
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 wsipv6ok.h (包括 Winsock2.h、Winsock.h)
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

GetAddrInfoEx

GetAddrInfoW

WSAAsyncGetHostByAddr

Winsock 函式

Winsock 參考

addrinfo

addrinfoW

getaddrinfo

gethostbyname

hostent