共用方式為


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_PASSIVE
0x01
套接字位址將用於 系結 函式的呼叫中。
AI_CANONNAME
0x02
標準名稱會在第一個 ai_canonname 成員中傳回。
AI_NUMERICHOST
0x04
傳遞至 GetAddrInfoW 函式的 nodename 參數必須是數值字串。
AI_ALL
0x0100
如果設定此位,則會針對具有 AI_V4MAPPED的 IPv6 位址和 IPv4 位址提出要求。

Windows Vista 和更新版本支援此選項。

AI_ADDRCONFIG
0x0400
只有在設定全域位址時 ,GetAddrInfoW 才會解析。 IPv6 和 IPv4 回送位址不被視為有效的全域位址。 只有 Windows Vista 和更新版本才支援此選項。
AI_V4MAPPED
0x0800
如果 IPv6 位址的 GetAddrInfoW 要求失敗,則會對 IPv4 位址提出名稱服務要求,而且這些位址會轉換成 IPv4 對應 IPv6 位址格式。

Windows Vista 和更新版本支援此選項。

AI_NON_AUTHORITATIVE
0x04000
地址資訊可以是來自非權威命名空間提供者。

只有 Windows Vista 和更新 NS_EMAIL 版本的命名空間才支援此選項。

AI_SECURE
0x08000
地址信息來自安全通道。

只有 Windows Vista 和更新 NS_EMAIL 版本的命名空間才支援此選項。

AI_RETURN_PREFERRED_NAMES
0x010000
地址資訊適用於使用者的慣用名稱。

只有 Windows Vista 和更新 NS_EMAIL 版本的命名空間才支援此選項。

AI_FQDN
0x00020000
如果指定單一標籤 (單一) 標籤標的一般名稱, GetAddrInfoW 會傳回最終解析名稱的完整功能變數名稱。 完整功能變數名稱會在 ai_canonname 成員中傳回。

這與傳回 DNS 中註冊標準名稱的 AI_CANONNAME 位旗標不同,可能與一般名稱解析為的完整功能變數名稱不同。

只能設定其中一個 AI_FQDNAI_CANONNAME 位。 如果兩個旗標都出現EAI_BADFLAGS,GetAddrInfoW 函式將會失敗。

Windows 7、Windows Server 2008 R2 及更新版本支援此選項。

AI_FILESERVER
0x00040000
命名空間提供者的提示,指出正在查詢的主機名正用於檔案共用案例中。 命名空間提供者可能會忽略此提示。

Windows 7、Windows Server 2008 R2 及更新版本支援此選項。

AI_DISABLE_IDN_ENCODING
0x00080000
GetAddrInfoW 函式所呼叫的名稱解析函式中使用 Punycode 停用自動國際域名編碼。

Windows 8、Windows Server 2012 及更新版本支援此選項。

ai_family

類型: int

位址系列。 位址系列的可能值定義在 Winsock2.h 頭檔中。

在針對 Windows Vista 和更新版本發行的 Windows SDK 上,頭檔的組織已變更,而且位址系列的可能值定義在 Ws2def.h 頭檔中。 請注意, Ws2def.h 頭文件會自動包含在 Winsock2.h 中,不應直接使用。

目前支援的值 AF_INETAF_INET6,這是 IPv4 和 IPv6 的因特網位址系列格式。 如果已安裝位址系列的 Windows Sockets 服務提供者, (AF_NETBIOS 用於 NetBIOS 的其他選項,例如,如果已安裝位址系列的 Windows 套接字服務提供者,則支援) 。 請注意,AF_位址系列和PF_通訊協定系列常數的值 (相同,例如 ,AF_UNSPECPF_UNSPEC) ,因此可以使用任一個常數。

下表列出位址系列常見的值,但可能有許多其他值。

意義
AF_UNSPEC
0
未指定位址系列。
AF_INET
2
因特網通訊協定第 4 版 (IPv4) 位址系列。
AF_NETBIOS
17
NetBIOS 位址系列。 只有在已安裝 NetBIOS 的 Windows Sockets 提供者時,才支援此位址系列。
AF_INET6
23
因特網通訊協定第 6 版 (IPv6) 位址系列。
AF_IRDA
26
IrDA (IrDA) 位址系列。 只有在計算機已安裝基礎結構埠和驅動程式時,才支援此位址系列。
AF_BTH
32
藍牙位址系列。 只有在 Windows Server 2003 或更新版本上安裝藍牙適配卡時,才支援此位址系列。

ai_socktype

類型: int

套接字類型。 套接字類型的可能值定義在 Winsock2.h 包含檔案中。

下表列出 Windows Sockets 2 支援的套接字類型可能值。

意義
SOCK_STREAM
1
使用 OOB 數據傳輸機制,提供循序、可靠、雙向的連線型位元組數據流。 針對因特網位址系列使用傳輸控制通訊協定 (TCP) (AF_INETAF_INET6) 。 如果 ai_family 成員 AF_IRDA則SOCK_STREAM 是唯一支援的套接字類型。
SOCK_DGRAM
2
支持數據報,這些數據報是無連接、不可靠的固定 (緩衝區通常很小) 最大長度。 針對因特網位址系列 (AF_INET或AF_INET6) 使用用戶數據報通訊協定 (UDP) 。
SOCK_RAW
3
提供原始套接字,可讓應用程式操作下一層通訊協議標頭。 若要操作 IPv4 標頭,必須在套接字上設定 IP_HDRINCL 套接字選項。 若要操作 IPv6 標頭,必須在套接字上設定 IPV6_HDRINCL 套接字選項。
SOCK_RDM
4
提供可靠的訊息數據報。 此類型的範例是 Windows 中的「實用一般多播」 (PGM) 多播通訊協議實作,通常稱為 可靠的多播程序設計
SOCK_SEQPACKET
5
根據數據報提供虛擬數據流封包。
 

在 Windows Sockets 2 中,引進了新的套接字類型。 應用程式可以透過 WSAEnumProtocols 函式動態探索每個可用傳輸通訊協議的屬性。 因此,應用程式可以判斷位址系列可能的套接字類型和通訊協定選項,並在指定此參數時使用此資訊。 Winsock2.hWs2def.h 頭檔中的套接字類型定義將會定期更新,因為定義了新的套接字類型、位址系列和通訊協定。

在 Windows Sockets 1.1 中,唯一可能的套接字類型是 SOCK_DATAGRAMSOCK_STREAM

ai_protocol

類型: int

通訊協定類型。 可能的選項專屬於指定的位址系列和套接字類型。 ai_protocol的可能值定義於 Winsock2.hWsrm.h 頭檔中。

在針對 Windows Vista 和更新版本發行的 Windows SDK 上,頭檔的組織已變更,而且此成員可以是 Ws2def.h 頭文件中定義之 IPPROTO 列舉類型的其中一個值。 請注意, Ws2def.h 頭文件會自動包含在 Winsock2.h 中,不應該直接使用。

如果為 ai_protocol指定 0 的值,則呼叫端不想要指定通訊協定,而服務提供者會選擇要使用的 ai_protocol 。 對於 IPv4 和 IPv6 以外的通訊協定,請將 ai_protocol 設為零。

下表列出 ai_protocol 成員的一般值,但可能有許多其他值。

意義
IPPROTO_TCP
6
傳輸控制通訊協定 (TCP) 。 當 ai_family 成員 AF_INETAF_INET6ai_socktype 成員 SOCK_STREAM時,這個值是可能的值。
IPPROTO_UDP
17
用戶數據報通訊協定 (UDP) 。 這是ai_family成員AF_INETAF_INET6類型參數SOCK_DGRAM時的可能值。
IPPROTO_RM
113
可靠多播的PGM通訊協定。 這是ai_family成員AF_INETai_socktype成員SOCK_RDM時的可能值。 在針對 Windows Vista 和更新版本發行的 Windows SDK 上,這個值也稱為IPPROTO_PGM
 

如果 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 型別指標的 nodenameservname 參數,以及 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_familyai_socktypeai_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)

另請參閱

GetAddrInfoEx

GetAddrInfoW

WSAEnumProtocols

addrinfo

addrinfoex

addrinfoex2

getaddrinfo

sockaddr