GetAddrInfoW 函数 (ws2tcpip.h)

GetAddrInfoW 函数提供从 Unicode 主机名到地址的与协议无关的转换。

语法

INT WSAAPI GetAddrInfoW(
  [in, optional] PCWSTR          pNodeName,
  [in, optional] PCWSTR          pServiceName,
  [in, optional] const ADDRINFOW *pHints,
  [out]          PADDRINFOW      *ppResult
);

参数

[in, optional] pNodeName

指向 以 NULL 结尾的 Unicode 字符串的指针,该字符串包含主机 (节点) 名称或数字主机地址字符串。 对于 Internet 协议,数字主机地址字符串是点十进制 IPv4 地址或 IPv6 十六进制地址。

[in, optional] pServiceName

指向以 NULL 结尾的 Unicode 字符串的指针,该字符串包含表示为字符串的服务名称或端口号。

服务名称是端口号的字符串别名。 例如,“http”是由 Internet 工程任务组定义的端口 80 的别名, (IETF) 作为 Web 服务器用于 HTTP 协议的默认端口。 以下文件中列出了未指定端口号时 pServiceName 参数的可能值:

%WINDIR%\system32\drivers\etc\services

[in, optional] pHints

指向 addrinfoW 结构的指针,该结构提供有关调用方支持的套接字类型的提示。

pHints 参数指向的 addrinfoW 结构的ai_addrlenai_canonnameai_addrai_next成员必须为零或 NULL。 否则, GetAddrInfoEx 函数将失败并 WSANO_RECOVERY

有关更多详细信息,请参阅备注。

[out] ppResult

指向包含主机相关响应信息的一个或多个 addrinfoW 结构的链接列表的指针。

返回值

成功返回零。 失败将返回非零 Windows 套接字错误代码,如 Windows 套接字错误代码中所示。

GetAddrInfoW 函数返回的大多数非零错误代码映射到 Internet 工程任务组概述的错误集 (IETF) 建议。 下表列出了这些错误代码及其 WSA 等效项。 建议使用 WSA 错误代码,因为它们为 Winsock 程序员提供熟悉且全面的错误信息。

错误值 WSA 等效项 说明
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 pHints 参数的指定ai_socktype成员不支持 pServiceName 参数。
EAI_SOCKTYPE WSAESOCKTNOSUPPORT 不支持 pHints 参数的 ai_socktype 成员。
 

使用 gai_strerror 函数根据 GetAddrInfoW 函数返回的 EAI_* 代码打印错误消息。 提供 gai_strerror 函数是为了符合 IETF 建议,但它不是线程安全的。 因此,建议使用传统的 Windows 套接字函数,例如 WSAGetLastError

错误代码 含义
WSA_NOT_ENOUGH_MEMORY
内存不足,无法执行操作。
WSAEAFNOSUPPORT
使用了与请求的协议不兼容的地址。 如果不支持 hints 参数指向的 addrinfoW 结构的 ai_family 成员,则返回此错误。
WSAEINVAL
提供的参数无效。 如果为 hints 参数指向的 addrinfoW 结构的 ai_flags 成员提供了无效值,则返回此错误。
WSAESOCKTNOSUPPORT
在此地址族中不存在对指定的套接字类型的支持。 如果不支持 hints 参数指向的 addrinfoW 结构的 ai_socktype 成员,则返回此错误。
WSAHOST_NOT_FOUND
无法识别这种主机。 如果所提供的参数的名称未解析,或者未提供 pNodenamepServicename 参数,则返回此错误。
WSANO_DATA
请求的名称有效,但找不到请求的类型的数据。
WSANO_RECOVERY
数据库查找期间发生不可恢复的错误。 如果名称解析中发生不可恢复的错误,则返回此错误。
WSANOTINITIALIZED
在使用此函数之前,必须成功调用 WSAStartup
WSATRY_AGAIN
这通常是主机名解析期间的临时错误,意味着本地服务器未接收到来自授权服务器的响应。 发生名称解析的临时失败时,将返回此错误。
WSATYPE_NOT_FOUND
未找到指定的类。 hints 参数指向的 addrinfoW 结构的指定ai_socktype成员不支持 pServiceName 参数。

注解

GetAddrInfoW 函数是一个函数的 Unicode 版本,它提供从主机名到地址的与协议无关的转换。 此函数的 ANSI 版本为 getaddrinfo

GetAddrInfoW 函数返回NS_DNS命名空间的结果。 如果多个命名空间提供程序返回信息, GetAddrInfoW 函数将聚合所有响应。 若要与 IPv6 和 IPv4 协议一起使用,可以通过域名系统 (DNS) 、本地 主机 文件或NS_DNS命名空间的其他命名机制进行 名称 解析。

Winsock 头文件中的宏定义 GetAddrInfoADDRINFOT 结构的混合大小写函数名称。 应使用 TCHAR 类型的指针的 pNodeNamepServiceName 参数以及 ADDRINFOT 类型指针的 pHintsppResult 参数调用此 GetAddrInfo 函数。 定义 UNICODE 或 _UNICODE 时, GetAddrInfo 定义为 GetAddrInfoW,函数的 Unicode 版本, ADDRINFOT 定义为 addrinfoW 结构。 如果未定义 UNICODE 或 _UNICODE, 则将 GetAddrInfo 定义为 getaddrinfo、函数的 ANSI 版本,而 ADDRINFOT 则定义为 addrinfo 结构。

一个或两个 pNodeNamepServiceName 参数必须指向 以 NULL 结尾的 Unicode 字符串;通常两者都提供。

成功后,将在 ppResult 参数中返回 addrinfoW 结构的链接列表。 可以通过遵循每个返回的 addrinfoW 结构的 ai_next 成员中提供的指针来处理列表,直到遇到 NULL 指针。 在每个返回的 addrinfoW 结构中, ai_familyai_socktypeai_protocol 成员对应于 套接字WSASocket 函数调用中的相应参数。 此外,每个返回的 addrinfoW 结构中的 ai_addr 成员指向填充的套接字地址结构,其长度在其ai_addrlen成员中指定。

如果 pNodeName 参数指向计算机名称,则返回可用作源地址的计算机的所有永久地址。 在 Windows Vista 及更高版本中,这些地址将包括 GetUnicastIpAddressTableGetUnicastIpAddressEntry 函数返回的所有单播 IP 地址,其中 SkipAsSource 成员在 MIB_UNICASTIPADDRESS_ROW 结构中设置为 false。

如果 pNodeName 参数指向等于“localhost”的字符串,则返回本地计算机上的所有环回地址。

如果 pNodeName 参数包含空字符串,则返回本地计算机上所有已注册的地址。

在 Windows Server 2003 及更高版本中,如果 pNodeName 参数指向等于“.”的字符串。localmachine“,返回本地计算机上所有已注册的地址。

如果 pNodeName 参数引用群集虚拟服务器名称,则仅返回虚拟服务器地址。 在 Windows Vista 及更高版本上,这些地址将包括 GetUnicastIpAddressTableGetUnicastIpAddressEntry 函数返回的所有单播 IP 地址,其中的 SkipAsSource 成员在 MIB_UNICASTIPADDRESS_ROW 结构中设置为 true。 有关 群集的详细信息,请参阅 Windows 群集。

Windows 7 Service Pack 1 (SP1) 和 Windows Server 2008 R2 service Pack 1 (SP1) 添加对 Netsh.exe 的支持,以在 IP 地址上设置 SkipAsSource 属性。 这还会更改行为,使MIB_UNICASTIPADDRESS_ROW结构中的 SkipAsSource 成员设置为 false,IP 地址将在 DNS 中注册。 如果 SkipAsSource 成员设置为 true,则 IP 地址未在 DNS 中注册。

修补程序适用于 Windows 7 和 Windows Server 2008 R2,这些修补程序支持 Netsh.exe 在 IP 地址上设置 SkipAsSource 属性。 此修补程序还会更改行为,以便如果MIB_UNICASTIPADDRESS_ROW结构中的 SkipAsSource 成员设置为 false,则会在 DNS 中注册 IP 地址。 如果 SkipAsSource 成员设置为 true,则 IP 地址未在 DNS 中注册。 有关详细信息,请参阅 知识库 (KB) 2386184

具有 Service Pack 2 (SP2) 的 Windows Vista 和 Windows Server 2008 Service Pack 2 (SP2) 也提供了类似的修补程序,为 Netsh.exe 添加对 IP 地址上设置 SkipAsSource 属性的支持。 此修补程序还会更改行为,以便如果MIB_UNICASTIPADDRESS_ROW结构中的 SkipAsSource 成员设置为 false,则会在 DNS 中注册 IP 地址。 如果 SkipAsSource 成员设置为 true,则 IP 地址未在 DNS 中注册。

GetAddrInfoW 函数的调用方可以提供有关通过 pHints 参数指向的 addrinfoW 结构支持的套接字类型的提示。 使用 pHints 参数时,以下规则将应用于其关联的 addrinfoW 结构:

  • 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

pHints 参数中提供的 addrinfoW 结构中的其他值指示特定要求。 例如,如果调用方仅处理 IPv4 而不处理 IPv6,则应将 ai_family 成员设置为 AF_INET。 对于另一个示例,如果调用方只处理 TCP 而不处理 UDP,则应将 ai_socktype 成员设置为 SOCK_STREAM

如果 pHints 参数为 NULL 指针,则 GetAddrInfoW 函数会像初始化 pHints 中的 addrinfoW 结构一样将其ai_family成员设置为 AF_UNSPEC,所有其他成员设置为零。

在 Windows Vista 及更高版本上,当从服务调用 GetAddrInfoW 时,如果操作是调用该服务的用户进程的结果,则服务应模拟该用户。 这是为了允许正确强制实施安全性。

GetAddrInfoW 函数可用于将 IP 地址的文本字符串表示形式转换为 addrinfoW 结构,该结构包含 IP 地址和其他信息的 sockaddr 结构。 若要以这种方式使用,pNodeName 参数指向的字符串必须包含 IP 地址的文本表示形式,并且 pHints 参数指向的 addrinfoW 结构必须在 ai_flags 成员中设置AI_NUMERICHOST标志。 pNodeName 参数指向的字符串可能包含 IPv4 或 IPv6 地址的文本表示形式。 文本 IP 地址转换为 ppResult 参数指向的 addrinfoW 结构。 返回的 addrinfoW 结构包含 IP 地址 的 sockaddr 结构以及有关 IP 地址的其他信息。 若要使用 Windows Server 2003 和 Windows XP 上的 IPv6 地址字符串,必须在本地计算机上安装 IPv6 协议。 否则,将返回 WSAHOST_NOT_FOUND 错误。

从动态分配中释放地址信息

由 ppResult 参数指向的 GetAddrInfoW 函数返回的所有信息都是动态分配的,包括所有 addrinfoW 结构、套接字地址结构和 addrinfoW 结构指向的规范主机名字符串。 成功调用此函数分配的内存必须与后续调用 FreeAddrInfoW 一起释放。

示例代码

下面的代码示例演示如何使用 GetAddrInfoW 函数。
#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")

// set APPVER=5.02 for WinXP SP2 and later

int __cdecl wmain(int argc, wchar_t **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult;
    INT iRetval;

    DWORD dwRetval;

    int i = 1;
    
    ADDRINFOW *result = NULL;
    ADDRINFOW *ptr = NULL;
    ADDRINFOW hints;

//    struct sockaddr_in6 *sockaddr_ipv6;
    LPSOCKADDR sockaddr_ip;

    wchar_t ipstringbuffer[46];
    DWORD ipbufferlength = 46;

    // Validate the parameters
    if (argc != 3) {
        wprintf(L"usage: %ws <hostname> <servicename>\n", argv[0]);
        wprintf(L"getaddrinfow provides protocol-independent translation\n");
        wprintf(L"   from an Unicode 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 getaddrinfo() function
    ZeroMemory( &hints, 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"\tnodename = %ws\n", argv[1]);
    wprintf(L"\tservname (or port) = %ws\n\n", argv[2]);
    

//--------------------------------
// Call GetAddrinfoW(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfow structures containing response
// information
    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");
                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;
                // 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)
                    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);
    }

    FreeAddrInfoW(result);
    WSACleanup();

    return 0;
}

注意 确保开发环境面向最新版本的 Ws2tcpip.h ,其中分别包括 addrinfoWGetAddrInfoW 的结构和函数定义。
 

国际化域名

Internet 主机名通常由一组非常受限的字符组成:
  • 英文字母表中的大小写 ASCII 字母。
  • 从 0 到 9 的数字。
  • ASCII 连字符。

随着 Internet 的发展,越来越需要为不由 ASCII 字符集表示的其他语言标识 Internet 主机名。 满足此需求并允许 Unicode) 表示为特殊 ASCII 字符串的非 ASCII 字符 (标识符称为国际化域名 (IDN) 。 (IDNA) 应用程序中称为国际化域名的机制用于以标准方式处理 IDN。 INTERNET 工程任务组 (IETF) 发布的 RFC 3490RTF 5890RFC 6365 中记录了 IDN 和 IDNA 的规范。

在 Windows 8 和 Windows Server 2012 上, GetAddrInfoW 函数支持国际化域名 (IDN) 分析应用于 pNodeName 参数中传递的名称。 Winsock 执行 Punycode/IDN 编码和转换。 可以使用下面讨论的 AI_DISABLE_IDN_ENCODING 标志禁用此行为。

在 Windows 7 和 Windows Server 2008 R2 或更早版本上, GetAddrInfoW 函数当前不支持应用于 pNodeName 参数中传递的名称的 IDN 分析。 Winsock 不执行任何 Punycode/IDN 转换。 根据 RFC 3490,GetAddrInfoW 函数不使用 Punycode 转换 IDN。 查询 DNS 时 ,GetAddrInfoW 函数以 UTF-8 格式对 Unicode 名称进行编码,这是企业环境中 Microsoft DNS 服务器使用的格式。

Windows Vista 和更高版本上的多个函数支持在 IDN 中的 Unicode 标签与其 ASCII 等效项之间进行转换。 每个 Unicode 标签的结果表示形式仅包含 ASCII 字符,并且如果 Unicode 标签包含任何非 ASCII 字符,则以 xn - 前缀开头。 这样做的原因是支持 Internet 上的现有 DNS 服务器,因为某些 DNS 工具和服务器仅支持 ASCII 字符 (请参阅 RFC 3490) 。

IdnToAscii 函数使用 Punycode,使用 RFC 3490 中定义的标准算法将 IDN 转换为原始 Unicode 字符串的 ASCII 表示形式。 IdnToUnicode 函数将 IDN 的 ASCII 形式转换为正常的 Unicode UTF-16 编码语法。 有关相关标准草案的详细信息和链接,请参阅处理国际化 域名 (IDN)

IdnToAscii 函数可用于将 IDN 名称转换为 ASCII 形式。 若要将此 ASCII 形式传递给 GetAddrInfoW 函数,可以使用 MultiByteToWideChar 函数将 CHAR 字符串转换为 WCHAR 字符串,然后可在 pNodeName 参数中将该字符串传递给 GetAddrInfoW 函数。

在 hints 参数中使用ai_flags

pHints 参数中提供的可选 addrinfoW 结构的 ai_flags 成员中的标志修改函数的行为。

这些标志位在适用于 Windows 7 的 Microsoft Windows 软件开发工具包 (SDK) 上的 Ws2def.h 头文件中定义。 这些标志位在 Windows SDK for Windows Server 2008 和 Windows Vista 上的 Ws2tcpip.h 头文件中定义。 这些标志位在适用于 Windows Server 2003 和 Windows XP 的平台软件开发工具包 (SDK) 上的 Ws2tcpip.h 头文件中定义。

标志位可以是以下各项的组合:

标记位 说明
AI_PASSIVE 设置 AI_PASSIVE 标志表示调用方打算在 调用绑定 函数时使用返回的套接字地址结构。 如果设置了 AI_PASSIVE 标志并且 pNodeNameNULL 指针,则套接字地址结构的 IP 地址部分将设置为 IPv4 地址的INADDR_ANY,对于 IPv6 地址 IN6ADDR_ANY_INIT

如果未设置 AI_PASSIVE 标志,则返回的套接字地址结构已准备好调用面向连接的协议的 connect 函数,或者已准备好调用无连接协议的 connectsendtosend 函数。 在这种情况下,如果 pNodeName 参数为 NULL 指针,则套接字地址结构的 IP 地址部分设置为环回地址。

AI_CANONNAME 如果未使用 AI_CANONNAMEAI_NUMERICHOST则 GetAddrInfoW 函数将尝试解析。 如果传递了文本字符串 ,GetAddrInfoW 将尝试转换字符串,如果传递了主机名, GetAddrInfoW 函数将尝试将名称解析为一个或多个地址。

设置 AI_CANONNAME 位后, pNodeName 参数不能为 NULL。 否则, GetAddrInfoEx 函数将失败并 WSANO_RECOVERY

设置AI_CANONNAME位且 GetAddrInfoW 函数返回成功时,ppResult 参数中的ai_canonname成员指向包含指定节点的规范名称的以 NULL 结尾的字符串。

注意设置AI_CANONNAME标志时,GetAddrInfoW 函数可以返回成功,但关联的 addrinfoW 结构中的ai_canonname成员为 NULL。 因此,建议使用 AI_CANONNAME 标志包括测试关联的 addrinfoW 结构中的 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 SDK for Windows Vista 及更高版本上定义。 Windows Vista 及更高版本支持 AI_ALL 标志。

AI_ADDRCONFIG 如果设置了 AI_ADDRCONFIG 位,则仅当配置了全局地址时 ,GetAddrInfoW 才会解析。 如果指定 了AI_ADDRCONFIG 标志,则仅当在本地系统上配置了 IPv4 地址时才返回 IPv4 地址,并且仅当在本地系统上配置了 IPv6 地址时,才返回 IPv6 地址。 IPv4 或 IPv6 环回地址不被视为有效的全局地址。

AI_ADDRCONFIG标志在 Windows SDK for Windows Vista 及更高版本上定义。 Windows Vista 及更高版本支持 AI_ADDRCONFIG 标志。

AI_V4MAPPED 如果设置了 AI_V4MAPPED 位,并且 IPv6 地址请求失败,则会对 IPv4 地址发出名称服务请求,这些地址将转换为 IPv4 映射的 IPv6 地址格式。

AI_V4MAPPED标志在 Windows SDK for Windows Vista 及更高版本上定义。 Windows Vista 及更高版本支持 AI_V4MAPPED 标志。

AI_NON_AUTHORITATIVE 如果设置了 AI_NON_AUTHORITATIVE 位, NS_EMAIL 命名空间提供程序将返回权威和非权威结果。 如果未设置 AI_NON_AUTHORITATIVE 位, 则NS_EMAIL 命名空间提供程序仅返回权威结果。

AI_NON_AUTHORITATIVE标志在 Windows SDK for Windows Vista 及更高版本上定义。 AI_NON_AUTHORITATIVE标志在 Windows Vista 及更高版本上受支持,仅适用于NS_EMAIL命名空间。

AI_SECURE 如果设置了 AI_SECURE 位, NS_EMAIL 命名空间提供程序将返回以增强的安全性获取的结果,以尽量减少可能的欺骗。

AI_SECURE标志在 Windows SDK for Windows Vista 及更高版本上定义。 Windows Vista 及更高版本支持 AI_SECURE 标志,仅适用于 NS_EMAIL 命名空间。

AI_RETURN_PREFERRED_NAMES 如果设置了 AI_RETURN_PREFERRED_NAMES ,则不应在 pNodeName 参数中提供任何名称。 NS_EMAIL命名空间提供程序将返回发布的首选名称。

AI_RETURN_PREFERRED_NAMES标志是在 Windows SDK for Windows Vista 及更高版本上定义的。 Windows Vista 及更高版本支持 AI_RETURN_PREFERRED_NAMES 标志,仅适用于 NS_EMAIL 命名空间。

AI_FQDN 如果设置了 AI_FQDN ,并且指定了单标签) (平面名称, 则 GetAddrInfoW 将返回该名称最终解析为的完全限定域名。 完全限定的域名在关联的 addrinfoW 结构的 ai_canonname 成员中返回。 这与返回 DNS 中注册的规范名称 AI_CANONNAME 位标志不同,该标志可能与平面名称解析为的完全限定域名不同。 只能设置 AI_FQDN 位和 AI_CANONNAME 位中的一个。 如果两个标志都带有EAI_BADFLAGS则 GetAddrInfoW 函数将失败。

设置 AI_FQDN 位时, pNodeName 参数不能为 NULL。 否则, GetAddrInfoEx 函数将失败并 WSANO_RECOVERY

Windows 7: AI_FQDN标志在 Windows SDK for Windows 7 及更高版本上定义。 Windows 7 及更高版本支持 AI_FQDN 标志。

AI_FILESERVER 如果设置了 AI_FILESERVER ,则会提示命名空间提供程序正在文件共享方案中使用正在查询的主机名。 命名空间提供程序可能会忽略此提示。

Windows 7: AI_FILESERVER标志在 Windows SDK for Windows 7 及更高版本上定义。 Windows 7 及更高版本支持 AI_FILESERVER 标志。

AI_DISABLE_IDN_ENCODING 如果设置了 AI_DISABLE_IDN_ENCODING ,则会在 GetAddrInfoW 函数调用的名称解析函数中使用 Punycode 禁用自动国际域名编码。

Windows 8: AI_DISABLE_IDN_ENCODING标志在 Windows SDK for Windows 8 及更高版本上定义。 Windows 8 及更高版本支持 AI_DISABLE_IDN_ENCODING 标志。

 

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。

注意

ws2tcpip.h 标头将 GetAddrInfo 定义为别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将非特定编码别名的使用与非非特定编码的代码混合使用可能会导致不匹配,从而导致编译或运行时错误。 有关详细信息,请参阅 函数原型的约定

要求

要求
最低受支持的客户端 Windows XP、Windows 8.1 [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 ws2tcpip.h
Library Ws2_32.lib
DLL Ws2_32.dll

另请参阅

FreeAddrInfoW

GetAddrInfoEx

GetHostNameW

IdnToAscii

IdnToUnicode

WSAGetLastError

WSASocket

Winsock 函数

Winsock 参考

addrinfo

addrinfoW

addrinfoex

addrinfoex2

bind

connect

gai_strerror

getaddrinfo

send

sendto

socket