gethostbyaddr 函式 (winsock.h)

[不再建議使用 gethostbyaddr 作為 Windows Sockets 2。 請改用 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 Sockets 實作不支援指定的 類型
WSAEFAULT
addr 參數不是用戶位址空間的有效部分,或 len 參數太小。
WSAEINTR
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall 取消。

備註

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

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

應用程式不應該嘗試釋放傳回 的主機實體 結構所使用的記憶體。 應用程式絕對不能嘗試修改此結構,或釋放其任何元件。 此外,每個線程只會配置此結構的一個複本,因此應用程式應該先複製它所需的任何資訊,再對 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 Store 應用程式支援此函式。

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)
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

GetAddrInfoEx

GetAddrInfoW

WSAAsyncGetHostByAddr

Winsock 函式

Winsock 參考

addrinfo

addrinfoW

getaddrinfo

gethostbyname

hostent