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 包含文件中定义,可以是以下选项的组合。

含义
AI_PASSIVE
0x01
套接字地址将在 调用绑定 函数时使用。
AI_CANONNAME
0x02
规范名称在第一个 ai_canonname 成员中返回。
AI_NUMERICHOST
0x04
传递给 GetAddrInfoEx 函数的 nodename 参数必须是数字字符串。
AI_ALL
0x0100
如果设置了此位,则会对具有 AI_V4MAPPED的 IPv6 地址和 IPv4 地址发出请求。

Windows Vista 及更高版本支持此选项。

AI_ADDRCONFIG
0x0400
仅当配置了全局地址时 ,GetAddrInfoEx 才会解析。 IPv6 和 IPv4 环回地址不被视为有效的全局地址。

Windows Vista 及更高版本支持此选项。

AI_V4MAPPED
0x0800
如果 IPv6 地址的 GetAddrInfoEx 请求失败,则会对 IPv4 地址发出名称服务请求,这些地址将转换为 IPv4 映射的 IPv6 地址格式。

Windows Vista 及更高版本支持此选项。

AI_NON_AUTHORITATIVE
0x04000
地址信息来自非权威结果。

GetAddrInfoExpHints 参数中设置此选项时,NS_EMAIL命名空间提供程序将返回权威和非权威结果。 如果未设置此选项,则仅返回权威结果。

此选项仅在 Windows Vista 及更高版本上支持 NS_EMAIL 命名空间。

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

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

GetAddrInfoExpHints 参数中设置此选项时,NS_EMAIL命名空间提供程序仅返回通过增强的安全性获取的结果,以最大程度地减少可能的欺骗。

此选项仅在 Windows Vista 及更高版本上支持 NS_EMAIL 命名空间。

AI_RETURN_PREFERRED_NAMES
0x010000
地址信息适用于具有特定命名空间的发布的首选名称。

GetAddrInfoExpHints 参数中设置此选项时,不应在 pName 参数中提供任何名称,NS_EMAIL命名空间提供程序将返回发布的首选名称。

此选项仅在 Windows Vista 及更高版本上支持 NS_EMAIL 命名空间。

AI_FQDN
0x00020000
完全限定的域名在第一 个ai_fqdn 成员中返回。

GetAddrInfoExpHints 参数中设置此选项并在 pName 参数中指定了单标签 (平面名称) 时,将返回该名称最终解析为的完全限定域名。

Windows 7、Windows Server 2008 R2 及更高版本支持此选项。

AI_FILESERVER
0x00040000
向命名空间提供程序提示正在文件共享方案中使用正在查询的主机名。 命名空间提供程序可能会忽略此提示。

Windows 7、Windows Server 2008 R2 及更高版本支持此选项。

AI_DISABLE_IDN_ENCODING
0x00080000
GetAddrInfoEx 函数调用的名称解析函数中使用 Punycode 禁用自动国际域名编码。

Windows 8、Windows Server 2012 及更高版本支持此选项。

AI_EXTENDED
0x80000000
指示当前对象已扩展:即 addrinfoex2 或更高版本。

Windows 8.1、Windows Server 2012 R2 及更高版本支持此选项。

AI_RESOLUTION_HANDLE
0x40000000
解析句柄在 ai_resolutionhandle 成员中返回。

Windows 10、Windows Server 2016 及更高版本支持此选项。

ai_family

地址系列。

地址系列的可能值在 Ws2def.h 头文件中定义。 请注意, Ws2def.h 头文件自动包含在 Winsock2.h 中,不应直接使用。

当前支持的值 是 AF_INETAF_INET6,即 IPv4 和 IPv6 的 Internet 地址系列格式。 AF_NETBIOS用于 NetBIOS 的地址系列 ( 的其他选项,例如,如果安装了地址系列的 Windows 套接字服务提供程序,则支持) 。 请注意,AF_地址系列和PF_协议系列常量的值 (相同,例如 ,AF_INETPF_INET) ,因此可以使用任一常量。

下表列出了地址系列的常见值,尽管可能还有其他许多值。

含义
AF_UNSPEC
0
未指定地址系列。
AF_INET
2
Internet 协议版本 4 (IPv4) 地址系列。
AF_NETBIOS
17
NetBIOS 地址系列。 仅当安装了适用于 NetBIOS 的 Windows 套接字提供程序时,才支持此地址系列。
AF_INET6
23
Internet 协议版本 6 (IPv6) 地址系列。
AF_IRDA
26
IrDA) 地址系列 (红外数据关联。 仅当计算机安装了红外端口和驱动程序时,才支持此地址系列。
AF_BTH
32
蓝牙地址系列。 仅当安装了蓝牙适配器时,才支持此地址系列。

ai_socktype

套接字类型。 套接字类型的可能值在 Winsock2.h include 文件中定义。

下表列出了 Windows 套接字 2 支持的套接字类型的可能值:

含义
SOCK_STREAM
1
提供具有 OOB 数据传输机制的有序、可靠、双向、基于连接的字节流。 将传输控制协议 (TCP) 用于 Internet 地址系列 (AF_INETAF_INET6) 。 如果ai_family成员AF_IRDA,SOCK_STREAM是唯一受支持的套接字类型。
SOCK_DGRAM
2
支持数据报,即最大长度固定(通常很小)的无连接、不可靠缓冲区。 将用户数据报协议 (UDP) 用于 Internet 地址系列 (AF_INETAF_INET6) 。
SOCK_RAW
3
提供允许应用程序操作下一层协议标头的原始套接字。 若要操作 IPv4 标头,必须在套接字上设置 IP_HDRINCL 套接字选项。 若要操作 IPv6 标头,必须在套接字上设置 IPV6_HDRINCL 套接字选项。
SOCK_RDM
4
提供可靠的消息数据报。 此类型的一个示例是 Windows 中的实用常规多播 (PGM) 多播协议实现,通常称为 可靠多播编程
SOCK_SEQPACKET
5
提供基于数据报的伪流数据包。
 

在 Windows 套接字 2 中,引入了新的套接字类型。 应用程序可以通过 WSAEnumProtocols 函数动态发现每个可用传输协议的属性。 因此,应用程序可以确定地址系列的可能的套接字类型和协议选项,并在指定此参数时使用此信息。 Winsock2.hWs2def.h 头文件中的套接字类型定义将随着新的套接字类型、地址系列和协议的定义而定期更新。

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

ai_protocol

协议类型。 可能的选项特定于指定的地址系列和套接字类型。 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_INET或AF_INET6ai_socktype成员SOCK_STREAM时,此值是可能的
IPPROTO_UDP
17
用户数据报协议 (UDP) 。 当ai_family成员AF_INET或AF_INET6类型参数SOCK_DGRAM时,此值可能为
IPPROTO_RM
113
可靠多播的 PGM 协议。 当ai_family成员AF_INET且ai_socktype成员为SOCK_RDM时,此值是可能的。 在 Windows Vista 及更高版本发布的Windows SDK中,此值也称为IPPROTO_PGM
 

如果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_bloblen 成员中指定 ai_blob 指向的缓冲区的长度 (以字节为单位 )。

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 结构

当通过 GetAddrInfoEx 传入addrinfoex4 成员中设置AI_EXTENDED | AI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE位时.ai_flags,GetAddrInfoEx 函数使用 addrinfoex4 结构保存主机地址信息。hints 参数。

addrinfoex4 结构是 addrinfoex 结构的增强版本,可以返回规范名称、主机的完全限定域名以及完全限定域名的句柄。 反过来,GetAddrInfoEx 是与 getaddrinfoGetAddrInfoW 函数一起使用的 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 后,将在传递给 GetAddrInfoEx 函数的 ppResult 参数中返回 addrinfoex4 结构的链接列表。 可以通过遵循每个返回的 addrinfoex4 结构的 ai_next 成员中提供的指针来处理列表,直到遇到 NULL 指针。 在每个返回的 addrinfoex4 结构中, ai_familyai_socktypeai_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

另请参阅

GetAddrInfoEx

addrinfo

addrinfoW

addrinfoex

addrinfoex3