addRINFOW 結構 (ws2def.h)
addrinfoW 結構是由 GetAddrInfoW 函式用來保存主機地址資訊。
語法
typedef struct addrinfoW {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
PWSTR ai_canonname;
struct sockaddr *ai_addr;
struct addrinfoW *ai_next;
} ADDRINFOW, *PADDRINFOW;
成員
ai_flags
類型: int
旗標,指出 GetAddrInfoW 函式中使用的選項。
ai_flags成員的支援值定義在 Winsock2.h 頭檔中,而且可以是下表所列的選項組合。
值 | 意義 |
---|---|
|
套接字位址將用於 系結 函式的呼叫中。 |
|
標準名稱會在第一個 ai_canonname 成員中傳回。 |
|
傳遞至 GetAddrInfoW 函式的 nodename 參數必須是數值字串。 |
|
如果設定此位,則會針對具有 AI_V4MAPPED的 IPv6 位址和 IPv4 位址提出要求。
Windows Vista 和更新版本支援此選項。 |
|
只有在設定全域位址時 ,GetAddrInfoW 才會解析。 IPv6 和 IPv4 回送位址不被視為有效的全域位址。 只有 Windows Vista 和更新版本才支援此選項。 |
|
如果 IPv6 位址的 GetAddrInfoW 要求失敗,則會對 IPv4 位址提出名稱服務要求,而且這些位址會轉換成 IPv4 對應 IPv6 位址格式。
Windows Vista 和更新版本支援此選項。 |
|
地址資訊可以是來自非權威命名空間提供者。
只有 Windows Vista 和更新 NS_EMAIL 版本的命名空間才支援此選項。 |
|
地址信息來自安全通道。
只有 Windows Vista 和更新 NS_EMAIL 版本的命名空間才支援此選項。 |
|
地址資訊適用於使用者的慣用名稱。
只有 Windows Vista 和更新 NS_EMAIL 版本的命名空間才支援此選項。 |
|
如果指定單一標籤 (單一) 標籤標的一般名稱, GetAddrInfoW 會傳回最終解析名稱的完整功能變數名稱。 完整功能變數名稱會在 ai_canonname 成員中傳回。
這與傳回 DNS 中註冊標準名稱的 AI_CANONNAME 位旗標不同,可能與一般名稱解析為的完整功能變數名稱不同。 只能設定其中一個 AI_FQDN 和 AI_CANONNAME 位。 如果兩個旗標都出現EAI_BADFLAGS,GetAddrInfoW 函式將會失敗。 Windows 7、Windows Server 2008 R2 及更新版本支援此選項。 |
|
命名空間提供者的提示,指出正在查詢的主機名正用於檔案共用案例中。 命名空間提供者可能會忽略此提示。
Windows 7、Windows Server 2008 R2 及更新版本支援此選項。 |
|
在 GetAddrInfoW 函式所呼叫的名稱解析函式中使用 Punycode 停用自動國際域名編碼。
Windows 8、Windows Server 2012 及更新版本支援此選項。 |
ai_family
類型: int
位址系列。 位址系列的可能值定義在 Winsock2.h 頭檔中。
在針對 Windows Vista 和更新版本發行的 Windows SDK 上,頭檔的組織已變更,而且位址系列的可能值定義在 Ws2def.h 頭檔中。 請注意, Ws2def.h 頭文件會自動包含在 Winsock2.h 中,不應直接使用。
目前支援的值 AF_INET 或 AF_INET6,這是 IPv4 和 IPv6 的因特網位址系列格式。 如果已安裝位址系列的 Windows Sockets 服務提供者, (AF_NETBIOS 用於 NetBIOS 的其他選項,例如,如果已安裝位址系列的 Windows 套接字服務提供者,則支援) 。 請注意,AF_位址系列和PF_通訊協定系列常數的值 (相同,例如 ,AF_UNSPEC 和 PF_UNSPEC) ,因此可以使用任一個常數。
下表列出位址系列常見的值,但可能有許多其他值。
ai_socktype
類型: int
套接字類型。 套接字類型的可能值定義在 Winsock2.h 包含檔案中。
下表列出 Windows Sockets 2 支援的套接字類型可能值。
值 | 意義 |
---|---|
|
使用 OOB 數據傳輸機制,提供循序、可靠、雙向的連線型位元組數據流。 針對因特網位址系列使用傳輸控制通訊協定 (TCP) (AF_INET 或 AF_INET6) 。 如果 ai_family 成員 AF_IRDA, 則SOCK_STREAM 是唯一支援的套接字類型。 |
|
支持數據報,這些數據報是無連接、不可靠的固定 (緩衝區通常很小) 最大長度。 針對因特網位址系列 (AF_INET或AF_INET6) 使用用戶數據報通訊協定 (UDP) 。 |
|
提供原始套接字,可讓應用程式操作下一層通訊協議標頭。 若要操作 IPv4 標頭,必須在套接字上設定 IP_HDRINCL 套接字選項。 若要操作 IPv6 標頭,必須在套接字上設定 IPV6_HDRINCL 套接字選項。 |
|
提供可靠的訊息數據報。 此類型的範例是 Windows 中的「實用一般多播」 (PGM) 多播通訊協議實作,通常稱為 可靠的多播程序設計。 |
|
根據數據報提供虛擬數據流封包。 |
在 Windows Sockets 2 中,引進了新的套接字類型。 應用程式可以透過 WSAEnumProtocols 函式動態探索每個可用傳輸通訊協議的屬性。 因此,應用程式可以判斷位址系列可能的套接字類型和通訊協定選項,並在指定此參數時使用此資訊。 Winsock2.h 和 Ws2def.h 頭檔中的套接字類型定義將會定期更新,因為定義了新的套接字類型、位址系列和通訊協定。
在 Windows Sockets 1.1 中,唯一可能的套接字類型是 SOCK_DATAGRAM 和 SOCK_STREAM。
ai_protocol
類型: int
通訊協定類型。 可能的選項專屬於指定的位址系列和套接字類型。 ai_protocol的可能值定義於 Winsock2.h 和 Wsrm.h 頭檔中。
在針對 Windows Vista 和更新版本發行的 Windows SDK 上,頭檔的組織已變更,而且此成員可以是 Ws2def.h 頭文件中定義之 IPPROTO 列舉類型的其中一個值。 請注意, Ws2def.h 頭文件會自動包含在 Winsock2.h 中,不應該直接使用。
如果為 ai_protocol指定 0 的值,則呼叫端不想要指定通訊協定,而服務提供者會選擇要使用的 ai_protocol 。 對於 IPv4 和 IPv6 以外的通訊協定,請將 ai_protocol 設為零。
下表列出 ai_protocol 成員的一般值,但可能有許多其他值。
如果 ai_family 成員 AF_IRDA, 則ai_protocol 必須為 0。
ai_addrlen
類型: size_t
ai_addr成員所指向之緩衝區的長度,以位元組為單位。
ai_canonname
類型: PWSTR
主機的正式名稱。
ai_addr
類型: 結構 sockaddr*
sockaddr 結構的指標。 每個傳回 ADDRINFOW 結構中的ai_addr成員會指向已填入的套接字地址結構。 每個傳回 之 ADDRINFOW 結構的長度,以位元組為單位,都會在 ai_addrlen 成員中指定。
ai_next
類型: struct addrinfoW*
連結清單中的下一個 結構的指標。 此參數會在連結清單的最後一個 addrinfoW 結構中設定為 NULL。
備註
AddrinfoW 結構是由 Unicode GetAddrInfoW 函式用來保存主機地址資訊。
addrinfo 結構是 ANSI getaddrinfo 函式所使用的這個結構的 ANSI 版本。
Ws2tcpip.h 頭檔中的宏會定義 ADDRINFOT 結構和 GetAddrInfo 的混合大小寫函式名稱。 GetAddrInfo 函式應該使用 TCHAR 型別指標的 nodename 和 servname 參數,以及 ADDRINFOT 型別指標的提示和 res 參數來呼叫。 定義 UNICODE 或_UNICODE時,ADDRINFOT 會定義至 addrinfoW 結構,並將 GetAddrInfo 定義為 GetAddrInfoW,這是此函式的 Unicode 版本。 未定義 UNICODE 或_UNICODE時, ADDRINFOT 會定義至 addrinfo 結構,並將 GetAddrInfo 定義為 getaddrinfo,這是此函式的 ANSI 版本。
成功呼叫 GetAddrInfoW 時,會將 ADDRINFOW 結構的連結清單傳回至 GetAddrInfoW 函式的 ppResult 參數中。 您可以依照每個傳回 ADDRINFOW 結構ai_next成員中提供的指標來處理清單,直到遇到 NULL 指標為止。 在每個傳回 的 ADDRINFOW 結構中, ai_family、 ai_socktype和 ai_protocol 成員會對應至 套接字 或 WSASocket 函數調用中的個別自變數。 此外,每個傳回 ADDRINFOW 結構中的ai_addr成員都會指向已填入的套接字地址結構,其ai_addrlen成員中指定的長度。
範例
下列程式代碼範例示範如何使用 addrinfoW 結構。
#ifndef UNICODE
#define UNICODE
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int __cdecl wmain(int argc, wchar_t ** argv)
{
//--------------------------------
// Declare and initialize variables.
WSADATA wsaData;
int iResult;
ADDRINFOW *result = NULL;
ADDRINFOW *ptr = NULL;
ADDRINFOW hints;
DWORD dwRetval = 0;
int i = 1;
struct sockaddr_in *sockaddr_ipv4;
struct sockaddr_in6 *sockaddr_ipv6;
// LPSOCKADDR sockaddr_ip;
wchar_t ipstringbuffer[46];
// Validate the parameters
if (argc != 3) {
wprintf(L"usage: %ws <hostname> <servicename>\n", argv[0]);
wprintf(L" provides protocol-independent translation\n");
wprintf(L" from a host name to an IP address\n");
wprintf(L"%ws example usage\n", argv[0]);
wprintf(L" %ws www.contoso.com 0\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;
}
//--------------------------------
// Setup the hints address info structure
// which is passed to the GetAddrInfoW() function
memset(&hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
wprintf(L"Calling GetAddrInfoW with following parameters:\n");
wprintf(L"\tName = %ws\n", argv[1]);
wprintf(L"\tServiceName (or port) = %ws\n\n", argv[2]);
//--------------------------------
// Call GetAddrInfoW(). If the call succeeds,
// the aiList variable will hold a linked list
// of addrinfo structures containing response
// information about the host
dwRetval = GetAddrInfoW(argv[1], argv[2], &hints, &result);
if (dwRetval != 0) {
wprintf(L"GetAddrInfoW failed with error: %d\n", dwRetval);
WSACleanup();
return 1;
}
wprintf(L"GetAddrInfoW returned success\n");
// Retrieve each address and print out the hex bytes
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
wprintf(L"GetAddrInfoW response %d\n", i++);
wprintf(L"\tFlags: 0x%x\n", ptr->ai_flags);
wprintf(L"\tFamily: ");
switch (ptr->ai_family) {
case AF_UNSPEC:
wprintf(L"Unspecified\n");
break;
case AF_INET:
wprintf(L"AF_INET (IPv4)\n");
// the InetNtop function is available on Windows Vista and later
sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
wprintf(L"\tIPv4 address %ws\n",
InetNtop(AF_INET, &sockaddr_ipv4->sin_addr, ipstringbuffer,
46));
// We could also use the WSAAddressToString function
// sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
// The buffer length is changed by each call to WSAAddresstoString
// So we need to set it for each iteration through the loop for safety
// ipbufferlength = 46;
// iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL,
// ipstringbuffer, &ipbufferlength );
// if (iRetval)
// wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError() );
// else
// wprintf(L"\tIPv4 address %ws\n", ipstringbuffer);
break;
case AF_INET6:
wprintf(L"AF_INET6 (IPv6)\n");
// the InetNtop function is available on Windows Vista and later
sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
wprintf(L"\tIPv6 address %ws\n",
InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr,
ipstringbuffer, 46));
// We could also use WSAAddressToString which also returns the scope ID
// sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
// The buffer length is changed by each call to WSAAddresstoString
// So we need to set it for each iteration through the loop for safety
// ipbufferlength = 46;
//iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL,
// ipstringbuffer, &ipbufferlength );
//if (iRetval)
// wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError() );
//else
// wprintf(L"\tIPv6 address %ws\n", ipstringbuffer);
break;
default:
wprintf(L"Other %ld\n", ptr->ai_family);
break;
}
wprintf(L"\tSocket type: ");
switch (ptr->ai_socktype) {
case 0:
wprintf(L"Unspecified\n");
break;
case SOCK_STREAM:
wprintf(L"SOCK_STREAM (stream)\n");
break;
case SOCK_DGRAM:
wprintf(L"SOCK_DGRAM (datagram) \n");
break;
case SOCK_RAW:
wprintf(L"SOCK_RAW (raw) \n");
break;
case SOCK_RDM:
wprintf(L"SOCK_RDM (reliable message datagram)\n");
break;
case SOCK_SEQPACKET:
wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)\n");
break;
default:
wprintf(L"Other %ld\n", ptr->ai_socktype);
break;
}
wprintf(L"\tProtocol: ");
switch (ptr->ai_protocol) {
case 0:
wprintf(L"Unspecified\n");
break;
case IPPROTO_TCP:
wprintf(L"IPPROTO_TCP (TCP)\n");
break;
case IPPROTO_UDP:
wprintf(L"IPPROTO_UDP (UDP) \n");
break;
default:
wprintf(L"Other %ld\n", ptr->ai_protocol);
break;
}
wprintf(L"\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
wprintf(L"\tCanonical name: %s\n", ptr->ai_canonname);
}
FreeAddrInfo(result);
WSACleanup();
return 0;
}
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows Vista、Windows XP SP2 [僅限傳統型應用程式] |
最低支援的伺服器 | Windows Server 2003 [僅限桌面應用程式] |
標頭 | ws2def.h (包含 Windows Server 2012、Windows 7 Windows Server 2008 R2) |