ADDRINFOEX4結構 (ws2def.h)
GetAddrInfoEx 函式會使用 addrinfoex4 結構,在要求特定網路介面時保存主機地址資訊。
語法
typedef struct addrinfoex4 {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
PWSTR ai_canonname;
struct sockaddr *ai_addr;
void *ai_blob;
size_t ai_bloblen;
GUID *ai_provider;
struct addrinfoex4 *ai_next;
int ai_version;
PWSTR ai_fqdn;
int ai_interfaceindex;
HANDLE ai_resolutionhandle;
} ADDRINFOEX4, *PADDRINFOEX4, *LPADDRINFOEX4;
成員
ai_flags
旗標,指出 GetAddrInfoEx 函式中使用的選項。
ai_flags成員的支援值定義於 Winsock2.h include 檔案中,而且可以是下列選項的組合。
值 | 意義 |
---|---|
|
套接字位址將用於對 bind 函式的呼叫。 |
|
標準名稱會在第一 個ai_canonname 成員中傳回。 |
|
傳遞至 GetAddrInfoEx 函式的 nodename 參數必須是數值字串。 |
|
如果設定此位,則會針對具有 AI_V4MAPPED的 IPv6 位址和 IPv4 位址提出要求。
Windows Vista 和更新版本支援此選項。 |
|
只有在設定全域位址時 ,GetAddrInfoEx 才會解析。 IPv6 和 IPv4 回送位址不會被視為有效的全域位址。
Windows Vista 和更新版本支援此選項。 |
|
如果 IPv6 位址的 GetAddrInfoEx 要求失敗,則會針對 IPv4 位址提出名稱服務要求,而且這些位址會轉換成 IPv4 對應 IPv6 位址格式。
Windows Vista 和更新版本支援此選項。 |
|
地址資訊來自非授權結果。
當此選項在 GetAddrInfoEx 的 pHints 參數中設定時,NS_EMAIL命名空間提供者會同時傳回授權和非授權結果。 如果未設定此選項,則只會傳回授權結果。 只有 windows Vista 和更新版本的 windows Vista 才支援此選項 ,NS_EMAIL 命名空間。 |
|
地址信息來自安全通道。
如果設定 AI_SECURE 位, NS_EMAIL 命名空間提供者會傳回以增強安全性取得的結果,以將可能的詐騙降到最低。 當此選項在 GetAddrInfoEx 的 pHints 參數中設定時,NS_EMAIL命名空間提供者只會傳回以增強安全性取得的結果,以將可能的詐騙降到最低。 只有 windows Vista 和更新版本的 windows Vista 才支援此選項 ,NS_EMAIL 命名空間。 |
|
地址資訊適用於具有特定命名空間之發行集的慣用名稱。
當此選項在 GetAddrInfoEx 的 pHints 參數中設定時,pName 參數中不應該提供任何名稱,而且NS_EMAIL命名空間提供者會傳回發行集的慣用名稱。 只有 windows Vista 和更新版本的 windows Vista 才支援此選項 ,NS_EMAIL 命名空間。 |
|
完整功能變數名稱會在第一個 ai_fqdn 成員中傳回。
在 GetAddrInfoEx 的 pHints 參數中設定此選項,並在 pName 參數中指定單一標籤 (單一卷標) 的一般名稱時,最終會傳回名稱的完整功能變數名稱。 Windows 7、Windows Server 2008 R2 和更新版本支援此選項。 |
|
命名空間提供者的提示,指出正在查詢的主機名正用於檔案共用案例中。 命名空間提供者可能會忽略此提示。
Windows 7、Windows Server 2008 R2 和更新版本支援此選項。 |
|
在 GetAddrInfoEx 函式所呼叫的名稱解析函式中使用 Punycode 停用自動國際域名編碼。
Windows 8、Windows Server 2012 及更新版本支援此選項。 |
|
表示目前的 對象已擴充:也就是 addrinfoex2 或更新版本。
Windows 8.1、Windows Server 2012 R2 和更新版本支援此選項。 |
|
解析句柄會在 ai_resolutionhandle 成員中傳回。
Windows 10、Windows Server 2016及更新版本支援此選項。 |
ai_family
位址系列。
位址系列的可能值定義在 Ws2def.h 頭檔中。 請注意, Ws2def.h 頭文件會自動包含在 Winsock2.h 中,不應該直接使用。
目前支援的值是 AF_INET 或 AF_INET6,這是IPv4和IPv6的因特網位址系列格式。 如果已安裝位址系列的 Windows Sockets 服務提供者,則支援位址系列 (AF_NETBIOS 用於 NetBIOS 的其他選項,例如,如果已安裝位址系列的 Windows 套接字服務提供者,則支援) 。 請注意,AF_位址系列和PF_通訊協定系列常數的值 (相同,例如, AF_INET 和 PF_INET) ,因此可以使用任一個常數。
下表列出位址系列的常見值,但可能有許多其他值。
ai_socktype
套接字類型。 套接字類型的可能值定義在 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
通訊協定類型。 可能的選項是指定的位址系列和套接字類型所特有。 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
ai_addr成員所指向之緩衝區的長度,以位元組為單位。
ai_canonname
主機的正式名稱。
ai_addr
sockaddr 結構的指標。 每個傳回 addrinfoex4 結構中的ai_addr成員會指向填入的套接字地址結構。 每個傳回 addrinfoex4 結構的長度,以位元組為單位,都會在 ai_addrlen 成員中指定。
ai_blob
數據指標,用來傳回與位址清單以外的名稱相關聯的提供者特定命名空間資訊。 ai_blob所指向之緩衝區的長度,以位元組為單位,必須在ai_bloblen成員中指定。
ai_bloblen
ai_blob成員的長度,以位元組為單位。
ai_provider
特定命名空間提供者之 GUID 的指標。
ai_next
連結清單中的下一個結構的指標。 此參數會在連結清單的最後一個 addrinfoex4 結構中設定為 NULL。
ai_version
這個結構的版本號碼。 目前用於此結構版本的值為 4。
ai_fqdn
主機的完整功能變數名稱。
ai_interfaceindex
介面索引,如IP_ADAPTER_ADDRESSES所定義。GetAdaptersAddresses 中傳回的 IfIndex 屬性。
ai_resolutionhandle
處理指向主機的完整功能變數名稱。
備註
Windows 10 和 Windows Server 2016 支援 addrinfoex4 結構
addrinfoex4 結構是由 GetAddrInfoEx 函式用來保存主機地址資訊,當 | AI_EXTENDEDAI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE位設定於透過 GetAddrInfoEx 傳入的 addrinfoex4.ai_flags 成員時。hints 參數。
addrinfoex4 結構是 addrinfoex 結構的增強版本,可傳回標準名稱、主機的完整功能變數名稱,以及完整功能變數名稱的句柄。 接著,GetAddrInfoEx 是搭配 getaddrinfo 和 GetAddrInfoW 函式使用的 addrinfo 和 addrinfoW 結構的增強版本。 GetAddrInfoEx 函式允許指定命名空間提供者來解析查詢。 為了與 IPv6 和 IPv4 通訊協定搭配使用,名稱解析可以是域名系統 (DNS) 、本機 主機 檔案、電子郵件提供者 (NS_EMAIL 命名空間) 或其他命名機制。
tha ai_blob 成員中的 Blob 資料可用來傳回與名稱相關聯的其他提供者特定命名空間資訊。 ai_blob成員中的數據格式是特定命名空間提供者特有的。 目前, NS_EMAIL 命名空間提供者會使用 Blob 數據來提供其他資訊。
定義 UNICODE 或_UNICODE時,addrinfoex4 會定義為 addrinfoex4W,這是這個結構的 Unicode 版本。 字串參數會定義至 PWSTR 數據類型,並使用 addrinfoex4W 結構。
未定義 UNICODE 或_UNICODE時, addrinfoex4 會定義為 addrinfoex4A,這是這個結構的 ANSI 版本。 字串參數屬於 char * 資料類型,並使用 addrinfoex4A 結構。
成功呼叫 GetAddrInfoEx 時,會將 addrinfoex4 結構的連結清單傳回至 GetAddrInfoEx 函式的 ppResult 參數中。 您可以依照每個傳回 addrinfoex4 結構之ai_next成員中提供的指標來處理清單,直到遇到 NULL 指標為止。 在每個傳回 的 addrinfoex4 結構中, ai_family、 ai_socktype和 ai_protocol 成員會對應到 套接字 或 WSASocket 函數調用中的個別自變數。 此外,每個傳回 addrinfoex4 結構中的ai_addr成員會指向填入的套接字地址結構,其ai_addrlen成員中指定的長度。
範例
下列程式代碼描述使用 addrinfoex4 結構呼叫 GetAddrInfoEx,以擷取 FQDN 的句柄。 然後,範例會使用 ASSOCIATE_NAMERES_CONTEXT_INPUT 結構呼叫 WSAIoctl。
//
// Connect to a server using its IPv4 addresses
//
VOID
ConnectServer(
PCWSTR server)
{
int iResult;
PADDRINFOEX4 pResult = NULL;
ADDRINFOEX3 hints = { 0 };
PADDRINFOEX4 pCur = NULL;
WSADATA wsaData;
SOCKET connectSocket = INVALID_SOCKET;
ULONG bytesReturned = 0;
ASSOCIATE_NAMERES_CONTEXT_INPUT input = { 0 };
SOCKADDR_IN clientService;
wchar_t ipstringbuffer[46];
String string;
DWORD dwRetval;
//
// Initialize Winsock
//
iResult = WSAStartup(
MAKEWORD(2, 2),
&wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
goto Exit;
}
//
// Create a SOCKET for connection
//
connectSocket = socket(
AF_UNSPEC,
SOCK_STREAM,
IPPROTO_TCP);
if (connectSocket == INVALID_SOCKET)
{
printf("socket failed: %d\n", WSAGetLastError());
goto Exit;
}
//
// Do name resolution
//
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_EXTENDED | AI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE;
hints.ai_version = ADDRINFOEX_VERSION_4;
dwRetval = GetAddrInfoExW(
server,
NULL,
NS_DNS,
NULL,
(const ADDRINFOEXW*)&hints,
(PADDRINFOEXW*)&pResult,
NULL,
NULL,
NULL, NULL);
if (dwRetval != 0) {
printf("GetAddrInfoEx failed with error: %d\n", dwRetval);
goto Exit;
}
input.TransportSettingId.Guid = ASSOCIATE_NAMERES_CONTEXT;
input.Handle = pResult->ai_resolutionhandle;
//
// Associate socket with the handle
//
if (WSAIoctl(
connectSocket,
SIO_APPLY_TRANSPORT_SETTING,
(VOID *)&input,
sizeof(input),
NULL,
0,
&bytesReturned,
NULL,
NULL) == SOCKET_ERROR)
if (iResult != 0){
printf("WSAIoctl failed: %d\n", WSAGetLastError());
goto Exit;
}
//
// Connect to server
//
pCur = pResult;
while (pCur != NULL)
{
if (pCur->ai_addr->sa_family == AF_INET)
{
clientService = *(const sockaddr_in*)pCur->ai_addr;
clientService.sin_port = htons(80);
if (connect(
connectSocket,
(const SOCKADDR *)&clientService,
sizeof(clientService)) == SOCKET_ERROR)
{
printf("connect failed: %d\n", WSAGetLastError());
goto Exit;
}
}
pCur = pCur->ai_next;
}
Exit:
if (connectSocket != INVALID_SOCKET)
{
closesocket(connectSocket);
}
if (pResult)
{
FreeAddrInfoExW((ADDRINFOEXW*)pResult);
}
WSACleanup();
return;
}
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 10 [僅限傳統型應用程式] |
最低支援的伺服器 | Windows Server 2016 [僅限傳統型應用程式] |
標頭 | ws2def.h |