共用方式為


getnameinfo 函式 (ws2tcpip.h)

getnameinfo 函式提供通訊協定無關的名稱解析,從位址到 ANSI 主機名,以及從埠號碼到 ANSI 服務名稱。

語法

INT WSAAPI getnameinfo(
  [in]  const SOCKADDR *pSockaddr,
  [in]  socklen_t      SockaddrLength,
  [out] PCHAR          pNodeBuffer,
  [in]  DWORD          NodeBufferSize,
  [out] PCHAR          pServiceBuffer,
  [in]  DWORD          ServiceBufferSize,
  [in]  INT            Flags
);

參數

[in] pSockaddr

套接字地址結構的指標,其中包含套接字的位址和埠號碼。 針對 IPv4,sa 參數會指向sockaddr_in結構。 針對 IPv6,sa 參數指向sockaddr_in6結構。

[in] SockaddrLength

sa 參數所指向之結構的長度,以位元組為單位。

[out] pNodeBuffer

用來保存主機名的 ANSI 字串指標。 成功時,主機名預設會以完整功能變數名稱的形式傳回 (FQDN) 。 如果 主機 參數為 NULL,這表示呼叫端不想要接收主機名字符串。

[in] NodeBufferSize

主機參數所指向之緩衝區的長度,以位元組為單位。 呼叫端必須提供足以保存主機名的緩衝區,包括終止 的NULL 字元。

[out] pServiceBuffer

要保存服務名稱的 ANSI 字串指標。 成功時,會傳回 ANSI 字串,代表與埠號碼相關聯的服務名稱。 如果 serv 參數為 NULL,這表示呼叫端不想要接收服務名稱字串。

[in] ServiceBufferSize

serv 參數所指向之緩衝區的長度,以位元組為單位。 呼叫端必須提供足以保存服務名稱的緩衝區,包括終止 的NULL 字元。

[in] Flags

值,用來自定義 getnameinfo 函式的處理。 請參閱<備註>一節。

傳回值

成功時, getnameinfo 會傳回零。 任何非零的傳回值都表示失敗,而且可以呼叫 WSAGetLastError 來擷取特定的錯誤碼。

getnameinfo 函式傳回的非零錯誤碼也會對應至 Internet Engineering Task Force (IETF 所概述的錯誤集) 建議。 下表列出這些錯誤碼及其 WSA 對等專案。 建議使用 WSA 錯誤碼,因為它們為 Winsock 程式設計人員提供熟悉且完整的錯誤資訊。

錯誤值 WSA 對等專案 Description
EAI_AGAIN WSATRY_AGAIN 發生名稱解析的暫時失敗。
EAI_BADFLAGS WSAEINVAL 一或多個無效的參數已傳遞至 getnameinfo 函式。 如果要求主機名,但 hostlen 參數為零,或要求服務名稱,但 servlen 參數為零,則會傳回此錯誤。
EAI_FAIL WSANO_RECOVERY 發生無法復原的名稱解析失敗。
EAI_FAMILY WSAEAFNOSUPPORT 不支援sa參數所指向的套接字地址結構sa_family成員。
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY 發生記憶體配置失敗。
EAI_NONAME WSAHOST_NOT_FOUND 要求服務名稱,但在 sa 參數所指向的結構中找不到埠號碼,或找不到符合埠號碼的服務名稱。 NI_NAMEREQD已設定且主機名無法找到,或 主機serv 參數皆為 NULL
 

使用 gai_strerror 函式,根據 getnameinfo 函式傳回的 EAI 代碼來列印錯誤訊息。 提供gai_strerror函式以符合 IETF 建議,但不是安全線程。 因此,建議使用傳統 Windows Sockets 函式,例如 WSAGetLastError

此外,可以傳回下列錯誤碼。

錯誤碼 意義
WSAEFAULT
如果 sa 參數為 NULLsalen 參數小於 IPv4 的 sockaddr_in 結構大小或 IPv6 sockaddr_in6 結構所需的長度,則會傳回此錯誤。

備註

getnameinfo 函式是提供通訊協定獨立名稱解析之函式的 ANSI 版本。 getnameinfo 函式可用來將套接字地址結構的內容轉譯為節點名稱和/或服務名稱。

針對 IPv6 和 IPv4 通訊協定,名稱解析可以是功能變數名稱系統 (DNS) 、本機 主機 檔案或其他命名機制。 此函式可用來判斷 IPv4 或 IPv6 位址的主機名、反向 DNS 查閱,或判斷埠號碼的服務名稱。 getnameinfo 函式也可以用來將sockaddr結構中的IP位址或埠號碼轉換成ANSI字串。 此函式也可以用來判斷主機名的IP位址。

另一個可用於 getnameinfo 函式的名稱是 GetNameInfoAWs2tcpip.h 頭檔中的宏會定義 GetNameInfoAgetnameinfo

此函式的 Unicode 版本可在 Windows XP 上使用 Service Pack 2 (SP2) 及更新版本為 GetNameInfoW

Winsock 頭檔中的宏會定義 GetNameInfo 的混合大小寫函式名稱,當應用程式以 SP2 和更新版本為目標時可以使用 (_WIN32_WINNT >= 0x0502) 。 此 GetNameInfo 函式應該使用 TCHAR 類型指標的 hostserv 參數呼叫。 未定義 UNICODE 或_UNICODE時,GetNameInfo 會定義為 ANSI 版本,並使用char 類型的指標主機和 serv 參數呼叫 getnameinfo。 定義 UNICODE 或_UNICODE時,GetNameInfo 會定義為 Unicode 版本,並使用 PWCHAR 類型的指標的 pNodeBuffer 和 pServiceBuffer 參數呼叫 GetNameInfoW

為了簡化 主機serv 參數的判斷緩衝區需求, Ws2tcpip.h 頭檔中定義了下列主機名長度上限和服務名稱上限的值。

#define NI_MAXSERV    32
#define NI_MAXHOST  1025

flags 參數可用來自定義 getnameinfo 函式的處理。 下列旗標可供使用:

  • NI_NOFQDN
  • NI_NUMERICHOST
  • NI_NAMEREQD
  • NI_NUMERICSERV
  • NI_DGRAM

設定 NI_NAMEREQD 旗標時,DNS 無法解析的主機名會導致錯誤。

設定 NI_NOFQDN 旗標會導致本機主機只有其相對辨別名稱 (RDN) 在 主機 參數中傳回。

設定 NI_NUMERICHOST 旗標會傳回主機名的數值形式,而不是其名稱。 如果 DNS 無法解析主機名,也會傳回主機名的數值形式。

設定 NI_NUMERICSERV 旗標會傳回服務的埠號碼,而不是其名稱。 此外,如果找不到IP位址的主機名, (127.0.0.2,例如) ,主機名會傳回為IP位址。

在 Windows Vista 和更新版本上,如果未在 flags 參數中指定NI_NUMERICSERV,且 sa 參數所指向的 sockaddr 結構中包含的埠號碼不會解析為已知的服務,getnameinfo 函式會傳回服務地址的數值形式, (埠號碼) 為數值字串。 指定 NI_NUMERICSERV 時,埠號碼會以數值字串的形式傳回。 此行為是在 RFC 3493 的 6.2 節中指定。 如需詳細資訊,請參閱 www.ietf.org/rfc3493.txt

在 Windows Server 2003 和更早版本上,如果未在 flags 參數中指定NI_NUMERICSERV,而且 sa 參數所指向的 sockaddr 結構中包含的埠號碼不會解析為已知的服務,getnameinfo 函式就會失敗。 指定 NI_NUMERICSERV 時,埠號碼會以數值字串的形式傳回。

設定 NI_DGRAM 旗標表示服務是數據報服務。 此旗標對於為 UDP 和 TCP 服務提供不同埠號碼的少數服務是必要的。

注意 使用 getnameinfo 函式執行反向 DNS 查閱的能力很方便,但這類查閱原本就不可靠,而且應該只當做提示使用。
 
注意getnameinfo 函式無法用來解析別名名稱。
 

範例程序代碼

下列程式代碼範例示範如何使用 getnameinfo 函式。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

// link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

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

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData = {0};
    int iResult = 0;

    DWORD dwRetval;

    struct sockaddr_in saGNI;
    char hostname[NI_MAXHOST];
    char servInfo[NI_MAXSERV];
    u_short port = 27015;

    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s IPv4 address\n", argv[0]);
        printf("  to return hostname\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;
    }
    //-----------------------------------------
    // Set up sockaddr_in structure which is passed
    // to the getnameinfo function
    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = inet_addr(argv[1]);
    saGNI.sin_port = htons(port);

    //-----------------------------------------
    // Call getnameinfo
    dwRetval = getnameinfo((struct sockaddr *) &saGNI,
                           sizeof (struct sockaddr),
                           hostname,
                           NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);

    if (dwRetval != 0) {
        printf("getnameinfo failed with error # %ld\n", WSAGetLastError());
        return 1;
    } else {
        printf("getnameinfo returned hostname = %s\n", hostname);
        return 0;
    }
}

舊版 Windows 上的 getnameinfo 支援

getnameinfo 函式已新增至 Windows XP 和更新版本的 Ws2_32.dll。 如果您想要在舊版 Windows (Windows 2000、Windows NT 和 Windows Me/98/95) 上使用此函式來執行應用程式,則需要包含 Ws2tcpip.h 檔案,並同時包含 Wspiapi.h 檔案。 新增 Wspiapi.h 包含檔案時, getnameinfo 函式會定義至 Wspiapi.h 檔案中的 WspiapiGetNameInfo 內嵌函式。 在運行時間,WspiapiGetNameInfo 函式的實作方式是,如果 Ws2_32.dllWship6.dll (Windows 200) 0 Technical Preview 中的 getnameinfo 檔案不包含 getnameinfo,則 getnameinfo 版本會根據 Wspiapi.h 頭檔中的程式代碼內嵌實作。 此內嵌程式代碼將用於原本不支援 getnameinfo 函式的舊版 Windows 平臺上。

安裝適用於 Windows 2000 的 IPv6 技術預覽版時,Windows 2000 支援 IPv6 通訊協定。 否則,在 Windows XP 之前的 Windows 版本上, getnameinfo 支援僅限於處理 IPv4 名稱解析。

GetNameInfoW 函式是 getnameinfo 的 Unicode 版本。 GetNameInfoW 函式已新增至 Windows XP SP2 中的 Ws2_32.dllGetNameInfoW 函式不能用於 Windows XP 與 SP2 之前的 Windows 版本。

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
標頭 ws2tcpip.h
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

GetNameInfoW

WSAGetLastError

Winsock 函式

Winsock 參考

gai_strerror

getaddrinfo

sockaddr