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已設定且主機名無法找到,或 pNodeBuffer 和 pServiceBuffer 參數都是 NULL。 |
您可以使用 gai_strerror 函式,根據 GetNameInfoW 函式傳回的 EAI 代碼來列印錯誤訊息。 gai_strerror函式是針對符合 IETF 建議的規範而提供,但不是安全線程。 因此,建議使用傳統 Windows Sockets 函式,例如 WSAGetLastError 。
此外,可以傳回下列錯誤碼。
錯誤碼 | 意義 |
---|---|
如果 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 型別指標的 pNodeBuffer 和 pServiceBuffer 參數來呼叫。 定義 UNICODE 或_UNICODE時,GetNameInfo 會定義為 Unicode 版本,並使用 char 類型的指標主機和 serv 參數呼叫 GetNameInfoW。 未定義 UNICODE 或_UNICODE時,GetNameInfo 會定義為 ANSI 版本,並使用 PWCHAR 型別指標的 pNodeBuffer 和 pServiceBuffer 參數呼叫 getnameinfo。
為了簡化 pNodeBuffer 和 pServiceBuffer 參數的判斷緩衝區需求, 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 服務提供不同埠號碼的少數服務而言是必要的。
Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。
Windows 8.1 和 Windows 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 |