getNameInfoW 函式 (ws2tcpip.h)

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

語法

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

參數

[in] pSockaddr

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

[in] SockaddrLength

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

[out] pNodeBuffer

要保存主機名之 Unicode 字串的指標。 成功時,Unicode 主機名的指標預設會以完整域名傳回, (FQDN) 。 如果 pNodeBuffer 參數為 NULL,這表示呼叫端不想接收主機名字符串。

[in] NodeBufferSize

pNodeBuffer 參數所指向之緩衝區中的 WCHAR 字元數目。 呼叫端必須提供足以保存 Unicode 主機名的緩衝區,包括終止 的 NULL 字元。

[out] pServiceBuffer

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

[in] ServiceBufferSize

pServiceBuffer 參數指向之緩衝區中的 WCHAR 字元數目。 呼叫端必須提供足以保存 Unicode 服務名稱的緩衝區,包括終止 的 NULL 字元。

[in] Flags

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

傳回值

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

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

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

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

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

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

備註

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

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

此函式的 ANSI 版本是 getnameinfo

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

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

#include <windows.h>

#define NI_MAXSERV    32
#define NI_MAXHOST  1025

Flags 參數可用來自定義 GetNameInfoW 函式的處理。 以下是可用的旗標:

  • NI_NOFQDN
  • NI_NUMERICHOST
  • NI_NAMEREQD
  • NI_NUMERICSERV
  • NI_DGRAM

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

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

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

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

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

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

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

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

Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更新版本上的 Windows 市集應用程式支援此函式。

範例程序代碼

下列範例示範 如何使用 GetNameInfoW 函式。
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#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;
    int iResult;

    DWORD dwRetval;

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

    // Validate the parameters
    if (argc != 2) {
        wprintf(L"usage: %s IPv4 address\n", argv[0]);
        wprintf(L"  to return hostname\n");
        wprintf(L"       %s 127.0.0.1\n", argv[0]);
        return 1;
    }
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"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 GetNameInfoW
    dwRetval = GetNameInfoW((struct sockaddr *) &saGNI,
                           sizeof (struct sockaddr),
                           hostname,
                           NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);

    if (dwRetval != 0) {
        wprintf(L"GetNameInfoW failed with error # %ld\n", WSAGetLastError());
        return 1;
    } else {
        wprintf(L"GetNameInfoW returned hostname = %ws\n", hostname);
        return 0;
    }
}

注意

ws2tcpip.h 標頭會將 GetNameInfo 定義為別名,根據 UNICODE 預處理器常數的定義,自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱 函式原型的慣例

規格需求

需求
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 ws2tcpip.h
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

GetAddrInfoW

WSAGetLastError

Winsock 函式

Winsock 參考

gai_strerror

getaddrinfo

getnameinfo

sockaddr