gethostbyname 函式 (winsock.h)

gethostbyname 函式會從主機資料庫擷取對應至主機名的主機資訊。

注意gethostbyname 函式已被 getaddrinfo 函式簡介所取代。 建立 Windows Sockets 2 應用程式的開發人員會鼓勵使用 getaddrinfo 函式,而不是 gethostbyname
 

語法

hostent * gethostbyname(
  const char *name
);

參數

name

TBD

傳回值

如果未發生任何錯誤, gethostbyname 會傳回上述 hostent 結構的指標。 否則,它會傳回 Null 指標,而且可以藉由呼叫 WSAGetLastError 來擷取特定的錯誤號碼。

錯誤碼 意義
WSANOTINITIALISED
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAENETDOWN
網路子系統失敗。
WSAHOST_NOT_FOUND
找不到授權回應主機。
WSATRY_AGAIN
找不到非授權主機,或伺服器失敗。
WSANO_RECOVERY
發生無法復原的錯誤。
WSANO_DATA
要求的名稱有效,但找不到所要求類型的數據。 如果 name 參數包含 IPv6 位址的字串表示或不合法的 IPv4 位址,也會傳回此錯誤。

這個錯誤不應該解譯為表示 name 參數包含已針對特定通訊協定驗證的名稱字串 (,例如) 。 由於 Winsock 支援多個名稱服務提供者,因此名稱可能對一個提供者有效,而且其他提供者不接受。

WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAEFAULT
name 參數不是使用者位址空間的有效部分。
WSAEINTR
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall 取消。

備註

gethostbyname 函式會傳回 hostent 結構的指標,這是 Windows Sockets 所配置的結構。 hostent 結構包含成功搜尋 name 參數中所指定主機的結果。

如果 name 參數中指定的主機同時具有 IPv4 和 IPv6 位址,則只會傳回 IPv4 位址。 gethostbyname 函式只能傳回 name 參數的 IPv4 位址。 如果需要主機的 IPv6 位址,或是需要主機的 IPv4 和 IPv6 位址,則應該使用 getaddrinfo 函式和相關聯的 addrinfo 結構。

如果 name 參數指向空字串或 名稱NULL,則傳回的字串與 成功 gethostname 函數呼叫所傳回的字串相同, (本機計算機的標準主機名) 。

如果 name 參數包含合法 IPv4 位址的字串表示法,則會在 hostent 結構中傳回代表字串的二進位 IPv4 位址。 hostent 結構的h_name成員包含 IPv4 位址的字串表示,而h_addr_list包含二進位 IPv4 位址。 如果 name 參數包含 IPv6 位址的字串表示法或不合法的 IPv4 位址, 則 gethostbyname 函式將會失敗並傳回 WSANO_DATA

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

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

gethostbyname 函式無法接受IP位址字串做為在名稱中傳遞給它的參數,並將它解析為主機名。 這類要求會完全視為 IPv4 位址的字串表示,或傳遞未知的主機名。 應用程式可以使用 inet_addr 將 IPv4 位址字串轉換成二進位 IPv4 位址,然後使用另一個 函式 gethostbyaddr 將 IPv4 位址解析為主機名。

注意gethostbyname 函式不會在傳遞緩衝區之前檢查 name 參數的大小。 使用大小不正確的 名稱 參數時,可能會發生堆積損毀。
 

範例程序代碼

下列範例示範 如何使用 gethostbyname 函式。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")

int main(int argc, char **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult;

    DWORD dwError;
    int i = 0;

    struct hostent *remoteHost;
    char *host_name;
    struct in_addr addr;

    char **pAlias;

    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s hostname\n", argv[0]);
        printf("  to return the IP addresses for the host\n");
        printf("       %s www.contoso.com\n", argv[0]);
        printf(" or\n");
        printf("       %s IPv4string\n", argv[0]);
        printf("  to return an IPv4 binary address for an IPv4string\n");
        printf("       %s 127.0.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_name = argv[1];

    printf("Calling gethostbyname with %s\n", host_name);
    remoteHost = gethostbyname(host_name);
    
    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_NETBIOS:
            printf("AF_NETBIOS\n");
            break;
        default:
            printf(" %d\n", remoteHost->h_addrtype);
            break;
        }
        printf("\tAddress length: %d\n", remoteHost->h_length);

        i = 0;
        if (remoteHost->h_addrtype == AF_INET)
        {
            while (remoteHost->h_addr_list[i] != 0) {
                addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
                printf("\tIP Address #%d: %s\n", i, inet_ntoa(addr));
            }
        }
        else if (remoteHost->h_addrtype == AF_NETBIOS)
        {   
            printf("NETBIOS address was returned\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

WSAAsyncGetHostByName

Winsock 函式

Winsock 參考

addrinfo

addrinfoW

getaddrinfo

gethostbyaddr

gethostname

hostent

inet_addr