getaddrinfo 函式 (ws2tcpip.h)

getaddrinfo 函式提供從 ANSI 主機名到地址的通訊協議獨立轉譯。

語法

INT WSAAPI getaddrinfo(
  [in, optional] PCSTR           pNodeName,
  [in, optional] PCSTR           pServiceName,
  [in, optional] const ADDRINFOA *pHints,
  [out]          PADDRINFOA      *ppResult
);

參數

[in, optional] pNodeName

NULL 終止的 ANSI 字串指標,其中包含主機 (節點) 名稱或數值主機位址字元串。 對於因特網通訊協議,數值主機位址字串是虛線十進位IPv4位址或IPv6 十六進位位址。

[in, optional] pServiceName

NULL 終止 ANSI 字串的指標,其中包含以字串表示的服務名稱或埠號碼。

服務名稱是埠號碼的字串別名。 例如,「HTTP」 是因特網工程工作組 (IETF 所定義的埠 80 別名,) 做為 Web 伺服器用於 HTTP 通訊協定的預設埠。 未指定埠號碼時 ,pServiceName 參數的可能值會列在下列檔案中:

%WINDIR%\system32\drivers\etc\services

[in, optional] pHints

addrinfo 結構的指標,提供呼叫端所支援套接字類型的提示。

pHints 參數所指向之 addrinfo 結構的ai_addrlenai_canonname、ai_addrai_next成員必須是零或 NULL。 否則 GetAddrInfoEx 函式將會失敗,並 WSANO_RECOVERY

如需詳細資訊,請參閱。

[out] ppResult

一或多個 addrinfo 結構鏈接清單的指標,其中包含主機的響應資訊。

傳回值

成功傳回零。 失敗會傳回非零的 Windows Sockets 錯誤碼,如 Windows 套接字錯誤碼中所找到。

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

錯誤值 WSA 對等專案 Description
EAI_AGAIN WSATRY_AGAIN 發生名稱解析的暫時失敗。
EAI_BADFLAGS WSAEINVAL pHints 參數ai_flags成員提供無效的值。
EAI_FAIL WSANO_RECOVERY 發生無法復原的名稱解析失敗。
EAI_FAMILY WSAEAFNOSUPPORT 不支援 pHints 參數ai_family成員。
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY 發生記憶體配置失敗。
EAI_NONAME WSAHOST_NOT_FOUND 未針對提供的參數解析名稱,或未提供 pNodeNamepServiceName 參數。
EAI_SERVICE WSATYPE_NOT_FOUND pServiceName 參數不支援 pHints 參數的指定ai_socktype成員。
EAI_SOCKTYPE WSAESOCKTNOSUPPORT 不支援 pHints 參數ai_socktype成員。
 

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

錯誤碼 意義
WSA_NOT_ENOUGH_MEMORY
記憶體不足,無法執行作業。
WSAEAFNOSUPPORT
已使用與要求通訊協定不相容的位址。 如果不支援 pHints 參數所指向的 addrinfo 結構ai_family成員,就會傳回此錯誤。
WSAEINVAL
提供的引數無效。 如果為 pHints 參數所指向之 addrinfo 結構ai_flags成員提供無效的值,就會傳回此錯誤。
WSAESOCKTNOSUPPORT
這個地址家族中不存在對指定通訊端類型的支援。 如果不支援 pHints 參數所指向的 addrinfo 結構ai_socktype成員,就會傳回此錯誤。
WSAHOST_NOT_FOUND
沒有已知的此類主機。 如果未針對提供的參數解析名稱,或未提供 pNodeNamepServiceName 參數,則會傳回此錯誤。
WSANO_DATA
要求的名稱有效,但找不到所要求類型的數據。
WSANO_RECOVERY
資料庫尋查期間發生無法復原的錯誤。 如果發生名稱解析中無法復原的錯誤,就會傳回此錯誤。
WSANOTINITIALISED
使用此函式之前,必須先進行成功的 WSAStartup 呼叫。
WSATRY_AGAIN
這通常為主機名稱解析期間的暫時錯誤,表示本機伺服器未收到授權伺服器的回應。 發生名稱解析暫時失敗時,就會傳回此錯誤。
WSATYPE_NOT_FOUND
找不到指定的類別。 pServiceName 參數不支援 pHints 參數所指向之 addrinfo 結構的指定ai_socktype成員。

備註

getaddrinfo 函式是函式的 ANSI 版本,可提供與主機名無關的通訊協定轉譯至位址。 此函式的 Unicode 版本是 GetAddrInfoW。 建議開發人員使用 GetAddrInfoW Unicode 函式,而不是 getaddrinfo ANSI 函式。

getaddrinfo 函式會傳回NS_DNS命名空間的結果。 如果有多個命名空間提供者傳回資訊, getaddrinfo 函式會匯總所有回應。 若要搭配 IPv6 和 IPv4 通訊協定使用,名稱解析可以透過功能變數名稱系統 (DNS) 、本機 主機 檔案,或 NS_DNS 命名空間的其他命名機制使用。

可用於 getaddrinfo 函式的另一個名稱是 GetAddrInfoAWs2tcpip.h 頭檔中的宏會定義 GetAddrInfoAgetaddrinfo

Ws2tcpip.h 頭檔中的宏會定義 GetAddrInfoADDRINFOT 結構的混合大小寫函式名稱。 這個 GetAddrInfo 函式應該使用 TCHAR 型別指標的 pNodeNamepServiceName 參數呼叫,以及 ADDRINFOT 型別指標的 pHintsppResult 參數。 未定義 UNICODE 或_UNICODE時, GetAddrInfo 會定義為 getaddrinfo、函式的 ANSI 版本,而 ADDRINFOT 會定義至 addrinfo 結構。 定義 UNICODE_UNICODE 時, GetAddrInfo 會定義為 GetAddrInfoW、函式的 Unicode 版本,而 ADDRINFOT 會定義至 addrinfoW 結構。

Windows Server 2003 的 Ws2tcpip.h 頭檔中所定義的 getaddrinfo 函式參數名稱和參數類型, (SDK) Windows Server 2003 和 Windows XP 不同。

pNodeNamepServiceName 參數的一或兩者都必須指向 NULL 終止的 ANSI 字串;通常會提供這兩者。

成功時,會在 ppResult 參數中傳回 addrinfo 結構的連結清單。 您可以依照每個傳回 addrinfo 結構ai_next成員中提供的指標來處理清單直到遇到 NULL 指標為止。 在每個傳回的 addrinfo 結構中, ai_familyai_socktypeai_protocol 成員會對應到 套接字WSASocket 函數調用中的個別自變數。 此外,每個傳回 addrinfo 結構中的ai_addr成員都會指向填入的套接字地址結構,其ai_addrlen成員中指定的長度。

如果 pNodeName 參數指向電腦名稱,則會傳回可用來做為來源地址的電腦的所有永久位址。 在 Windows Vista 和更新版本上,這些位址會包含 GetUnicastIpAddressTableGetUnicastIpAddressEntry 函式傳回的所有單播 IP 位址, 其中 SkipAsSource 成員在 MIB_UNICASTIPADDRESS_ROW 結構中設定為 false。

如果 pNodeName 參數指向等於 「localhost」 的字串,則會傳回本機電腦上的所有回送位址。

如果 pNodeName 參數包含空字串,則會傳回本機電腦上所有已註冊的位址。

如果 pNodeName 參數指向等於 “.” 的字串,在 Windows Server 2003 和更新版本上。localmachine“,會傳回本機計算機上所有已註冊的位址。

如果 pNodeName 參數參考叢集虛擬伺服器名稱,則只會傳回虛擬伺服器位址。 在 Windows Vista 和更新版本上,這些位址會包含 GetUnicastIpAddressTableGetUnicastIpAddressEntry 函式傳回的所有單播 IP 位址, 其中 SkipAsSource 成員在 MIB_UNICASTIPADDRESS_ROW 結構中設定為 true。 如需叢集的詳細資訊,請參閱 Windows 叢集

Windows 7 Service Pack 1 (SP1) 和 Windows Server 2008 R2 with Service Pack 1 (SP1) 新增支援至 Netsh.exe,以在 IP 位址上設定 SkipAsSource 屬性。 這也會變更行為,如此一來,如果 MIB_UNICASTIPADDRESS_ROW 結構中的SkipAsSource成員設定為 false,IP 位址將會在 DNS 中註冊。 如果 SkipAsSource 成員設定為 true,則不會在 DNS 中註冊 IP 位址。

Hotfix 適用於 Windows 7 和 Windows Server 2008 R2,可新增對 Netsh.exe 的支援,以在 IP 位址上設定 SkipAsSource 屬性。 此 Hotfix 也會變更行為,如此一來,如果 MIB_UNICASTIPADDRESS_ROW 結構中的 SkipAsSource 成員設定為 false,IP 位址將會在 DNS 中註冊。 如果 SkipAsSource 成員設定為 true,則不會在 DNS 中註冊 IP 位址。 如需詳細資訊,請參閱 知識庫 (KB) 2386184

Windows Vista 的 Service Pack 2 (SP2) 和 Windows Server 2008 Service Pack 2 (SP2) 也提供類似的 Hotfix,可新增對 Netsh.exe 的支援,以在 IP 位址上設定 SkipAsSource 屬性。 此 Hotfix 也會變更行為,如此一來,如果 MIB_UNICASTIPADDRESS_ROW 結構中的 SkipAsSource 成員設定為 false,IP 位址將會在 DNS 中註冊。 如果 SkipAsSource 成員設定為 true,則不會在 DNS 中註冊 IP 位址。

getaddrinfo 函式的呼叫端可以提供 pHints 參數所指向之 addrinfo 結構所支援的套接字類型提示。 使用 pHints 參數時,下列規則會套用至其相關聯的 addrinfo 結構:

  • ai_family的 AF_UNSPEC 值表示呼叫端只會接受AF_INETAF_INET6位址系列。 請注意, AF_UNSPECPF_UNSPEC 相同。
  • ai_socktype值為零 表示呼叫端將接受任何套接字類型。
  • ai_protocol的值為零,表示呼叫端將接受任何通訊協定。
  • ai_addrlen成員必須設定為零。
  • ai_canonname成員必須設定為NULL
  • ai_addr成員必須設定為NULL
  • ai_next成員必須設定為NULL

ai_family 的 AF_UNSPEC 值表示呼叫端將接受任何通訊協定系列。 這個值可用來針對 pNodeName 參數所指向的主機名,同時傳回 IPv4 和 IPv6 位址。 只有在本機計算機上安裝 IPv6 時,才會在 Windows Server 2003 和 Windows XP 上傳回 IPv6 位址。

pHints 參數中提供的 addrinfo 結構中的其他值會指出特定需求。 例如,如果呼叫端只處理 IPv4 且未處理 IPv6, 則ai_family 成員應該設定為 AF_INET。 針對另一個範例,如果呼叫端只處理 TCP 且未處理 UDP, 則ai_socktype 成員應該設定為 SOCK_STREAM

如果 pHints 參數是 NULL 指標,getaddrinfo 函式會將它視為 pHints 中的 addrinfo 結構已初始化,並將其ai_family成員設定為 AF_UNSPEC,而所有其他成員都設定為零。

在 Windows Vista 和更新版本上,從服務呼叫 getaddrinfo 時,如果作業是呼叫服務的用戶進程的結果,則服務應該模擬使用者。 這是為了允許正確強制執行安全性。

getaddrinfo 函式可用來將IP位址的文字字串表示轉換成 addrinfo 結構,其中包含IP位址和其他資訊的sockaddr結構。 若要以這種方式使用,pNodeName 參數所指向的字串必須包含IP位址的文字表示法,而 pHints 參數所指向的 addrinfo 結構必須設定ai_flags成員中的AI_NUMERICHOST旗標。 pNodeName 參數所指向的字串可能包含 IPv4 或 IPv6 位址的文字表示。 文字 IP 位址會轉換成 ppResult 參數所指向的 addrinfo 結構。 傳回的 addrinfo 結構包含 IP 位址 的 sockaddr 結構,以及 IP 位址的新增資訊。 若要讓此方法在 Windows Server 2003 和 Windows XP 上使用 IPv6 位址字串,IPv6 通訊協議必須安裝在本機電腦上。 否則,會傳回 WSAHOST_NOT_FOUND 錯誤。

從動態配置釋放地址資訊

ppResult 參數所指向 getaddrinfo 函式所傳回的所有信息都會動態配置,包括 addrinfo 結構、套接字地址結構,以及 addrinfo 結構所指向的標準主機名字符串。 成功呼叫此函式所配置的記憶體必須釋放,且後續呼叫 freeaddrinfo

範例程序代碼

下列程式代碼範例示範如何使用 getaddrinfo 函式。
#undef UNICODE

#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;
    INT iRetval;

    DWORD dwRetval;

    int i = 1;
    
    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;

    struct sockaddr_in  *sockaddr_ipv4;
//    struct sockaddr_in6 *sockaddr_ipv6;
    LPSOCKADDR sockaddr_ip;

    char ipstringbuffer[46];
    DWORD ipbufferlength = 46;

    // Validate the parameters
    if (argc != 3) {
        printf("usage: %s <hostname> <servicename>\n", argv[0]);
        printf("getaddrinfo provides protocol-independent translation\n");
        printf("   from an ANSI host name to an IP address\n");
        printf("%s example usage\n", argv[0]);
        printf("   %s www.contoso.com 0\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    //--------------------------------
    // Setup the hints address info structure
    // which is passed to the getaddrinfo() function
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    printf("Calling getaddrinfo with following parameters:\n");
    printf("\tnodename = %s\n", argv[1]);
    printf("\tservname (or port) = %s\n\n", argv[2]);
    
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
    dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
    if ( dwRetval != 0 ) {
        printf("getaddrinfo failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }

    printf("getaddrinfo returned success\n");
    
    // Retrieve each address and print out the hex bytes
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("\tIPv4 address %s\n",
                    inet_ntoa(sockaddr_ipv4->sin_addr) );
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                // the InetNtop function is available on Windows Vista and later
                // sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
                // printf("\tIPv6 address %s\n",
                //    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );
                
                // We use WSAAddressToString since it is supported on Windows XP and later
                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)
                    printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
                else    
                    printf("\tIPv6 address %s\n", ipstringbuffer);
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
        printf("\tSocket type: ");
        switch (ptr->ai_socktype) {
            case 0:
                printf("Unspecified\n");
                break;
            case SOCK_STREAM:
                printf("SOCK_STREAM (stream)\n");
                break;
            case SOCK_DGRAM:
                printf("SOCK_DGRAM (datagram) \n");
                break;
            case SOCK_RAW:
                printf("SOCK_RAW (raw) \n");
                break;
            case SOCK_RDM:
                printf("SOCK_RDM (reliable message datagram)\n");
                break;
            case SOCK_SEQPACKET:
                printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_socktype);
                break;
        }
        printf("\tProtocol: ");
        switch (ptr->ai_protocol) {
            case 0:
                printf("Unspecified\n");
                break;
            case IPPROTO_TCP:
                printf("IPPROTO_TCP (TCP)\n");
                break;
            case IPPROTO_UDP:
                printf("IPPROTO_UDP (UDP) \n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_protocol);
                break;
        }
        printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        printf("\tCanonical name: %s\n", ptr->ai_canonname);
    }

    freeaddrinfo(result);
    WSACleanup();

    return 0;
}

注意 請確定開發環境以最新版 的 Ws2tcpip.h 為目標,分別包含 addrinfogetaddrinfo 的結構和函式定義。
 

國際化功能變數名稱

因特網主機名通常包含一組非常受限的字元:
  • 大寫和小寫的英文 ASCII 字母。
  • 0 到 9 位數。
  • ASCII 連字元字元。

隨著因特網的成長,需要識別 ASCII 字元集未表示之其他語言的因特網主機名。 有助於此需求的標識符,並允許 Unicode (Unicode) 的非 ASCII 字元表示為特殊 ASCII 字元字串,稱為國際功能變數名稱 (IDN) 。 在應用程式 (IDNA) 中將域名國際化的機制,可用來以標準方式處理 IDN。 IDN 和 IDNA 的規格記載於 INTERNET Engineering Task Force (IETF) 所發佈的 RFC 3490RTF 5890RFC 6365 中。

在 Windows 8 和 Windows Server 2012 上,getaddrinfo 函式支持國際化域名 (IDN) 剖析套用至 pNodeName 參數中傳遞的名稱。 Winsock 會執行 Punycode/IDN 編碼和轉換。 您可以使用下面討論 的AI_DISABLE_IDN_ENCODING 旗標來停用此行為。

在 Windows 7 和 Windows Server 2008 R2 或更早版本上, getaddrinfo 函式目前不提供套用至 pNodeName 參數中所傳遞名稱的支援 IDN 剖析。 Winsock 不會執行任何 Punycode/IDN 轉換。 GetAddrInfo 函式的寬字元版本不會使用 Punycode 根據 RFC 3490 轉換 IDN。 查詢 DNS 時 ,GetAddrInfo 函式的寬字元版本會以 UTF-8 格式編碼 Unicode 名稱,這是企業環境中 Microsoft DNS 伺服器所使用的格式。

Windows Vista 和更新版本的數個函式支援在 IDN 中的 Unicode 標籤與其 ASCII 對等專案之間的轉換。 每個 Unicode 標籤的結果表示只包含 ASCII 字元,如果 Unicode 標籤包含任何非 ASCII 字元,則開頭為 xn-- 前置詞。 原因是支援因特網上的現有 DNS 伺服器,因為某些 DNS 工具和伺服器僅支援 ASCII 字元, (請參閱 RFC 3490) 。

IdnToAscii 函式會使用 Punycode,使用 RFC 3490 中定義的標準演算法,將 IDN 轉換成原始 Unicode 字串的 ASCII 表示法。 IdnToUnicode 函式會將IDN的 ASCII形式轉換為一般的 Unicode UTF-16 編碼語法。 如需相關草稿標準的詳細資訊和連結,請參閱 處理國際化功能變數名稱 (IDN)

IdnToAscii 函式可用來將 IDN 名稱轉換為 ASCII 表單,然後可在 pNodeName 參數中傳遞至 getaddrinfo 函式。 若要將這個 IDN 名稱傳遞至 GetAddrInfo 函式,當 UNICODE 或_UNICODE定義) 時, (使用此函式的寬字元版本時,您可以使用 MultiByteToWideChar 函數將 CHAR 字串轉換成 WCHAR 字串。

在 pHints 參數中使用ai_flags

pHints 參數中提供的選擇性 addrinfo結構ai_flags成員中的旗標會修改函式的行為。

這些旗標位定義於適用於 Windows 7 的 Microsoft Windows 軟體開發套件 (SDK) Ws2def.h 頭檔中。 這些旗標位定義於 Windows Server 2008 和 Windows Vista Windows SDK 上的 Ws2tcpip.h 頭檔中。 這些旗標位定義於 Windows Server 2003 平臺 SDK 和 Windows XP 的 Ws2tcpip.h 頭檔中。

旗標位可以是下列各項的組合:

標幟位 Description
AI_PASSIVE 設定 AI_PASSIVE 旗標表示呼叫端想要在系 函式的呼叫中使用傳回的套接字地址結構。 當 設定AI_PASSIVE 旗標且 pNodeNameNULL 指標時,套接字地址結構的 IP 位址部分會設定為 IPv4 位址 的 INADDR_ANY,而 IPv6 位址IN6ADDR_ANY_INIT

未設定 AI_PASSIVE 旗標時,傳回的套接字地址結構已準備好呼叫連線導向通訊協定的 連線 函式,或準備好呼叫 連線傳送或傳送無連線通訊協定的 式。 如果 pNodeName 參數在此案例中為 NULL 指標,套接字地址結構的 IP 位址部分會設定為回送位址。

AI_CANONNAME 如果未使用AI_CANONNAMEAI_NUMERICHOST,getaddrinfo 函式會嘗試解析。 如果傳遞常值字串 getaddrinfo 會嘗試轉換字串串,而且如果傳遞主機名, getaddrinfo 函式會嘗試將名稱解析為位址或多個位址。

設定 AI_CANONNAME 位時, pNodeName 參數不能是 NULL。 否則 getaddrinfo 函式將會失敗,並 WSANO_RECOVERY

設定AI_CANONNAME位且 getaddrinfo 函式傳回成功時,ppResult 參數中的ai_canonname成員會指向包含指定節點標準名稱的 NULL 終止字串。

注意設定AI_CANONNAME旗標時,getaddrinfo 函式可以傳回成功,但相關聯 addrinfo 結構中的ai_canonname成員為 NULL。 因此,建議使用AI_CANONNAME旗標包括測試相關聯 addrinfo 結構中的ai_canonname成員是否為 NULL
 
AI_NUMERICHOST 設定 AI_NUMERICHOST 位時, pNodeName 參數必須包含非 NULL 數值主機位址字串,否則會傳回 EAI_NONAME 錯誤。 此旗標可防止呼叫名稱解析服務。
AI_NUMERICSERV 設定 AI_NUMERICSERV 位時, pServiceName 參數必須包含非 NULL 數值埠號碼,否則會傳回 EAI_NONAME 錯誤。 此旗標可防止呼叫名稱解析服務。

AI_NUMERICSERV旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Microsoft 提供者不支援 AI_NUMERICSERV 旗標。

AI_ALL 如果 已設定AI_ALL 位,則會針對具有 AI_V4MAPPED的 IPv6 位址和 IPv4 位址提出要求。

AI_ALL旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Windows Vista 和更新版本支援 AI_ALL 旗標。

AI_ADDRCONFIG 如果 已設定AI_ADDRCONFIG 位, getaddrinfo 只會在設定全域位址時解析。 如果指定 了AI_ADDRCONFIG 旗標,則只有在本機系統上設定IPv4位址時,才會傳回IPv4 位址,而且只有在本機系統上設定IPv6 位址時,才會傳回 IPv6 位址。 IPv4 或 IPv6 回送位址不會被視為有效的全域位址。

AI_ADDRCONFIG旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Windows Vista 和更新版本支援 AI_ADDRCONFIG 旗標。

AI_V4MAPPED 如果 已設定AI_V4MAPPED 位,且 IPv6 位址的要求失敗,則會對 IPv4 位址提出名稱服務要求,而且這些位址會轉換成 IPv4 對應 IPv6 位址格式。

AI_V4MAPPED旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Windows Vista 和更新版本支援 AI_V4MAPPED 旗標。

AI_NON_AUTHORITATIVE 如果 已設定AI_NON_AUTHORITATIVE 位, 則NS_EMAIL 命名空間提供者會同時傳回授權和非授權結果。 如果未設定 AI_NON_AUTHORITATIVE 位, 則NS_EMAIL 命名空間提供者只會傳回授權結果。

AI_NON_AUTHORITATIVE旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Windows Vista 和更新版本支援 AI_NON_AUTHORITATIVE 旗標,並僅適用於 NS_EMAIL 命名空間。

AI_SECURE 如果 已設定AI_SECURE 位, NS_EMAIL 命名空間提供者會傳回以增強安全性取得的結果,以將可能的詐騙降到最低。

AI_SECURE旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Windows Vista 和更新版本支援 AI_SECURE 旗標,僅適用於 NS_EMAIL 命名空間。

AI_RETURN_PREFERRED_NAMES 如果 已設定AI_RETURN_PREFERRED_NAMES ,則 pNodeName 參數中不應該提供任何名稱。 NS_EMAIL命名空間提供者會傳回發行集的慣用名稱。

AI_RETURN_PREFERRED_NAMES旗標是在 Windows Vista 和更新版本的 Windows SDK 上定義。 Windows Vista 和更新版本支援 AI_RETURN_PREFERRED_NAMES 旗標,僅適用於 NS_EMAIL 命名空間。

AI_FQDN 如果 已設定AI_FQDN ,且指定單一標籤 (一般名稱 ) ,getaddrinfo 會傳回最終解析名稱的完整功能變數名稱。 完整功能變數名稱會在相關聯 addrinfo 結構的ai_canonname成員中傳回。 這與傳回 DNS 中註冊標準名稱的 AI_CANONNAME 位旗標不同,可能與一般名稱解析為的完整功能變數名稱不同。 只能設定其中一個 AI_FQDNAI_CANONNAME 位。 如果兩個旗標都存在EAI_BADFLAGS,getaddrinfo 函式將會失敗。

設定 AI_FQDN 位時, pNodeName 參數不能是 NULL。 否則 GetAddrInfoEx 函式將會失敗,並 WSANO_RECOVERY

Windows 7: AI_FQDN旗標是在 Windows 7 和更新版本的 Windows SDK 上定義。 Windows 7 和更新版本支援 AI_FQDN 旗標。

AI_FILESERVER 如果 已設定AI_FILESERVER ,這是要查詢的主機名用於檔案共用案例的命名空間提供者提示。 命名空間提供者可能會忽略此提示。

Windows 7: AI_FILESERVER旗標是在 Windows 7 和更新版本的 Windows SDK 上定義。 Windows 7 和更新版本支援 AI_FILESERVER 旗標。

 

使用 AI_NUMERICHOST 的範例程序代碼

下列程式代碼範例示範如何使用 getaddrinfo 函式,將 IP 位址的文字字串表示轉換成 addrinfo 結構,其中包含 IP 位址和其他資訊的 sockaddr 結構。
#undef UNICODE

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

    int i = 1;
    
    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;


    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s <IP Address String>\n", argv[0]);
        printf("  getaddrinfo determines the IP binary network address\n");
        printf("       %s 207.46.197.32\n", argv[0]);  /* www.contoso.com */
        return 1;
    }
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    //--------------------------------
    // Setup the hints address info structure
    // which is passed to the getaddrinfo() function
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_flags = AI_NUMERICHOST;
    hints.ai_family = AF_UNSPEC;
//    hints.ai_socktype = SOCK_STREAM;
//    hints.ai_protocol = IPPROTO_TCP;


//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
    dwRetval = getaddrinfo(argv[1], NULL, &hints, &result);
    if ( dwRetval != 0 ) {
        printf("getaddrinfo failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }

    printf("getaddrinfo returned success\n");
    
    // Retrieve each address and print out the hex bytes
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
        printf("\tSocket type: ");
        switch (ptr->ai_socktype) {
            case 0:
                printf("Unspecified\n");
                break;
            case SOCK_STREAM:
                printf("SOCK_STREAM (stream)\n");
                break;
            case SOCK_DGRAM:
                printf("SOCK_DGRAM (datagram) \n");
                break;
            case SOCK_RAW:
                printf("SOCK_RAW (raw) \n");
                break;
            case SOCK_RDM:
                printf("SOCK_RDM (reliable message datagram)\n");
                break;
            case SOCK_SEQPACKET:
                printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_socktype);
                break;
        }
        printf("\tProtocol: ");
        switch (ptr->ai_protocol) {
            case 0:
                printf("Unspecified\n");
                break;
            case IPPROTO_TCP:
                printf("IPPROTO_TCP (TCP)\n");
                break;
            case IPPROTO_UDP:
                printf("IPPROTO_UDP (UDP) \n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_protocol);
                break;
        }
        printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        printf("\tCanonical name: %s\n", ptr->ai_canonname);
    }

    freeaddrinfo(result);
    WSACleanup();

    return 0;
}

支援 Windows 2000 和舊版上的 getaddrinfo

getaddrinfo 函式已新增至 Windows XP 和更新版本的 Ws2_32.dll。 若要在舊版 Windows 上執行使用此函式的應用程式,您需要包含 Ws2tcpip.hWspiapi.h 檔案。 新增 Wspiapi.h 包含檔案時, getaddrinfo 函式會定義至 WspiapiGetAddrInfo 內嵌函式 Wspiapi.h 檔案中。 在運行時間,WspiapiGetAddrInfo 函式會以這種方式實作,如此一來,如果 windows 200) 0 技術預覽版中的 Ws2_32.dll 或 Wship6.dll (包含 getaddrinfo 的檔案,就不會包含 getaddrinfo,然後根據 Wspiapi.h 頭檔中的程式代碼實作 getaddrinfo 版本。 此內嵌程式代碼將用於原生不支援 getaddrinfo 函式的舊版 Windows 平臺上。

安裝適用於 Windows 2000 的 IPv6 技術預覽版時,Windows 2000 支援 IPv6 通訊協定。 否則,在 Windows XP 之前的 Windows 版本上 ,getaddrinfo 支援僅限於處理 IPv4 名稱解析。

GetAddrInfoW 函式是 getaddrinfo 的 Unicode 版本。 GetAddrInfoW 函式已新增至 Windows XP 中的 Ws2_32.dll service Pack 2 (SP2) 。 GetAddrInfoW 函式不能用於 Windows XP 與 SP2 之前的 Windows 版本。

Windows Phone 8:Windows Phone 8 和更新版本 Windows Phone 市集應用程式支援此函式。

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

規格需求

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

另請參閱

GetAddrInfoEx

GetAddrInfoW

IdnToAscii

IdnToUnicode

WSAGetLastError

WSASocket

Winsock 函式

Winsock 參考

addrinfo

addrinfoW

addrinfoex

addrinfoex2

bind

connect

freeaddrinfo

gai_strerror

send

sendto

socket