Поделиться через


Структура ADDRINFOEXA (ws2def.h)

Структура addrinfoex используется функцией GetAddrInfoEx для хранения сведений об адресе узла.

Синтаксис

typedef struct addrinfoexA {
  int                ai_flags;
  int                ai_family;
  int                ai_socktype;
  int                ai_protocol;
  size_t             ai_addrlen;
  char               *ai_canonname;
  struct sockaddr    *ai_addr;
  void               *ai_blob;
  size_t             ai_bloblen;
  LPGUID             ai_provider;
  struct addrinfoexA *ai_next;
} ADDRINFOEXA, *PADDRINFOEXA, *LPADDRINFOEXA;

Члены

ai_flags

Тип: int

Флаги, указывающие параметры, используемые в функции GetAddrInfoEx.

Поддерживаемые значения для элемента ai_flags определены в Winsock2.h включить файл и могут быть сочетанием следующих параметров.

Ценность Значение
AI_PASSIVE
0x01
Адрес сокета будет использоваться в вызове функции привязки привязки.
AI_CANONNAME
0x02
Каноническое имя возвращается в первом элементе ai_canonname.

Если заданы AI_CANONNAME и AI_FQDN биты, возвращается структура addrinfoex2 не addrinfoex.

AI_NUMERICHOST
0x04
Параметр nodename, переданный функции GetAddrInfoEx, должен быть числовой строкой.
AI_ALL
0x0100
Если этот бит задан, запрос выполняется для IPv6-адресов и IPv4-адресов с AI_V4MAPPED.

Этот параметр поддерживается в Windows Vista и более поздних версиях.

AI_ADDRCONFIG
0x0400
GetAddrInfoEx будет разрешаться только в том случае, если настроен глобальный адрес. Адрес обратного цикла IPv6 и IPv4 не считается допустимым глобальным адресом.

Этот параметр поддерживается только в Windows Vista и более поздних версиях.

AI_V4MAPPED
0x0800
Если запрос GetAddrInfoEx для IPv6-адресов завершается сбоем, запрос службы имен выполняется для IPv4-адресов, и эти адреса преобразуются в формат IPv4-адресов, сопоставленных с IPv6.

Этот параметр поддерживается в Windows Vista и более поздних версиях.

AI_NON_AUTHORITATIVE
0x04000
Сведения об адресе являются неавторитетными результатами.

Если этот параметр задан в параметре pHintsGetAddrInfoEx, поставщик пространства имен NS_EMAIL возвращает как достоверные, так и неавторитетные результаты. Если этот параметр не задан, возвращаются только достоверные результаты.

В параметре ppResults, возвращаемом GetAddrInfoEx, этот флаг задается в элементе ai_flags структуры addrinfoex для неавторитетных результатов.

Этот параметр поддерживается только в Windows Vista и более поздних версиях для пространства имен NS_EMAIL.

AI_SECURE
0x08000
Сведения об адресе — из безопасного канала. Если задан AI_SECURE бит, поставщик пространства имен NS_EMAIL вернет результаты, полученные с повышенной безопасностью для минимизации возможных спуфингов.

Если этот параметр задан в параметре pHintsGetAddrInfoEx, поставщик пространства имен NS_EMAIL возвращает только результаты, полученные с повышенной безопасностью, чтобы свести к минимуму возможный спуфинг.

В параметре ppResults, возвращаемом GetAddrInfoEx, этот флаг задается в элементе ai_flags структуры addrinfoex для результатов, возвращаемых с повышенной безопасностью, чтобы свести к минимуму возможный спуфинг.

Этот параметр поддерживается только в Windows Vista и более поздних версиях для пространства имен NS_EMAIL.

AI_RETURN_PREFERRED_NAMES
0x010000
Сведения об адресе — это предпочитаемые имена для публикации с определенным пространством имен.

Если этот параметр задан в параметре pHintsGetAddrInfoEx, имя не должно быть указано в параметре pName, а поставщик пространства имен NS_EMAIL вернет предпочтительные имена для публикации.

В параметре ppResults, возвращаемом GetAddrInfoEx, этот флаг задается в элементе ai_flags структуры addrinfoex для результатов, возвращаемых для предпочитаемых имен публикации.

Этот параметр поддерживается только в Windows Vista и более поздних версиях для пространства имен NS_EMAIL.

AI_FQDN
0x00020000
Полное доменное имя возвращается в первом элементе ai_canonicalname.

Если этот параметр задан в параметре pHintsGetAddrInfoEx, а в параметре pName указано неструктурированное имя, полное доменное имя, которое будет возвращено в конечном итоге.

Если заданы AI_CANONNAME и AI_FQDN биты, возвращается структура addrinfoex2 не addrinfoex.

Этот параметр поддерживается в Windows 7, Windows Server 2008 R2 и более поздних версиях.

AI_FILESERVER
0x00040000
Указание поставщику пространства имен, которое запрашивается имя узла в сценарии общей папки. Поставщик пространства имен может игнорировать это указание.

Этот параметр поддерживается в Windows 7, Windows Server 2008 R2 и более поздних версиях.

AI_DISABLE_IDN_ENCODING
0x00080000
Отключите автоматическую кодировку международного доменного имени с помощью Punycode в функциях разрешения имен, вызываемых функцией GetAddrInfoEx.

Этот параметр поддерживается в Windows 8, Windows Server 2012 и более поздних версиях.

ai_family

Тип: int

Семейство адресов. Возможные значения для семейства адресов определяются в файле Winsock2.h.

В пакете SDK для Windows Vista и более поздних версий организация файлов заголовков изменилась, а возможные значения для семейства адресов определяются в файле заголовка Ws2def.h. Обратите внимание, что файл заголовка ws2def.h Ws2def.h автоматически включается в Winsock2.hи никогда не следует использовать напрямую.

В настоящее время поддерживаются значения AF_INET или AF_INET6, которые являются форматами семейства адресов Интернета для IPv4 и IPv6. Другие варианты семейства адресов (AF_NETBIOS для использования с NetBIOS, например), поддерживаются, если установлен поставщик служб сокетов Windows для семейства адресов. Обратите внимание, что значения для семейства адресов AF_ и констант семейства протоколов PF_ идентичны (например, AF_UNSPEC и PF_UNSPEC), поэтому можно использовать любую константу.

В таблице ниже перечислены распространенные значения семейства адресов, хотя возможны многие другие значения.

Ценность Значение
AF_UNSPEC
0
Семейство адресов не указано.
AF_INET
2
Семейство адресов протокола Интернета версии 4 (IPv4).
AF_NETBIOS
17
Семейство адресов NetBIOS. Это семейство адресов поддерживается только в том случае, если установлен поставщик сокетов Windows для NetBIOS.
AF_INET6
23
Семейство адресов протокола Интернета версии 6 (IPv6).
AF_IRDA
26
Семейство адресов связи с инфракрасным данными (IrDA). Это семейство адресов поддерживается только в том случае, если на компьютере установлен инфракрасный порт и драйвер.
AF_BTH
32
Семейство адресов Bluetooth. Это семейство адресов поддерживается только в том случае, если адаптер Bluetooth установлен в Windows Server 2003 или более поздней версии.

ai_socktype

Тип: int

Тип сокета. Возможные значения для типа сокета определяются в файле Winsock2.h включить файл.

В следующей таблице перечислены возможные значения типа сокета, поддерживаемого для сокетов Windows 2:

Ценность Значение
SOCK_STREAM
1
Предоставляет последовательные, надежные, двусторонние потоки байтов на основе подключения с механизмом передачи данных OOB. Использует протокол TCP для семейства адресов Интернета (AF_INET или AF_INET6). Если элемент ai_familyAF_IRDA, SOCK_STREAM является единственным поддерживаемым типом сокета.
SOCK_DGRAM
2
Поддерживает диаграммы данных, которые являются ненадежными, ненадежными буферами фиксированной (обычно небольшой) максимальной длины. Использует протокол пользовательской диаграммы данных (UDP) для семейства адресов Интернета (AF_INET или AF_INET6).
SOCK_RAW
3
Предоставляет необработанный сокет, позволяющий приложению управлять следующим заголовком протокола верхнего уровня. Чтобы управлять заголовком IPv4, необходимо задать параметр сокета IP_HDRINCL на сокете. Чтобы управлять заголовком IPv6, необходимо задать параметр сокета IPV6_HDRINCL на сокете.
SOCK_RDM
4
Предоставляет надежную диаграмму данных сообщений. Примером этого типа является реализация многоадресной многоадресной рассылки (PGM) прагматичной многоадресной рассылки в Windows, часто называемая надежным многоадресным программированием.
SOCK_SEQPACKET
5
Предоставляет псевдопотоковый пакет на основе диаграмм данных.
 

В Windows Sockets 2 появились новые типы сокетов. Приложение может динамически обнаруживать атрибуты каждого доступного транспортного протокола с помощью функции WSAEnumProtocols. Поэтому приложение может определить возможный тип сокета и параметры протокола для семейства адресов и использовать эти сведения при указании этого параметра. Определения типов сокетов в Winsock2.h и Ws2def.h файлы заголовков будут периодически обновляться как новые типы сокетов, семейства адресов и протоколы.

В Сокетах Windows 1.1 единственными возможными типами сокетов являются SOCK_DATAGRAM и SOCK_STREAM.

ai_protocol

Тип: int

Тип протокола. Возможные параметры зависят от указанного семейства адресов и типа сокета. Возможные значения для ai_protocol определены в Winsock2.h и файлах заголовков Wsrm.h Wsrm.h.

В пакете SDK для Windows SDK, выпущенном для Windows Vista и более поздних версий, организация файлов заголовков изменилась, и этот элемент может быть одним из значений из типа перечисления IPPROTO, определенного в файле заголовка Ws2def.h. Обратите внимание, что файл заголовка ws2def.h Ws2def.h автоматически включается в Winsock2.hи никогда не следует использовать напрямую.

Если для ai_protocolзадано значение 0, вызывающий объект не хочет указать протокол, и поставщик услуг выберет ai_protocol для использования. Для протоколов, отличных от IPv4 и IPv6, задайте для ai_protocol значение нулю.

В следующей таблице перечислены распространенные значения элемента ai_protocol, хотя можно использовать множество других значений.

Ценность Значение
IPPROTO_TCP
6
Протокол управления передачей (TCP). Это возможное значение, если элемент ai_familyAF_INET или AF_INET6, а элемент ai_socktypeSOCK_STREAM.
IPPROTO_UDP
17
Протокол пользовательской диаграммы данных (UDP). Это возможное значение, если элемент ai_familyAF_INET или AF_INET6, а параметр типаSOCK_DGRAM.
IPPROTO_RM
113
Протокол PGM для надежной многоадресной рассылки. Это возможное значение, если элемент ai_familyAF_INET, а элемент ai_socktypeSOCK_RDM. В пакете SDK для Windows, выпущенном для Windows Vista и более поздних версий, это значение также называется IPPROTO_PGM.
 

Если элемент ai_familyAF_IRDA, ai_protocol должен быть равен 0.

ai_addrlen

Тип: size_t

Длина буфера в байтах, на который указывает элемент ai_addr.

ai_canonname

Тип: PCTSTR

Каноническое имя узла.

ai_addr

Тип: структуры sockaddr*

Указатель на структуру sockaddr. Элемент ai_addr в каждом возвращаемом addrinfoex указывает на структуру адресов сокета, заполненную. Длина в байтах каждого возвращаемого addrinfoex структура указывается в элементе ai_addrlen.

ai_blob

Тип: void*

Указатель на данные, используемые для возврата сведений о пространстве имен для конкретного поставщика, связанных с именем за пределами списка адресов. Длина буфера в байтах, на который указывает ai_blob, должна быть указана в элементе ai_bloblen.

ai_bloblen

Тип: size_t

Длина элемента ai_blob в байтах.

ai_provider

Тип: LPGUID

Указатель на GUID определенного поставщика пространства имен.

ai_next

Тип: структуры addrinfoex*

Указатель на следующую структуру в связанном списке. Этот параметр имеет значение NULL в последней addrinfoex структуре связанного списка.

Замечания

Структура addrinfoex используется функцией GetAddrInfoEx для хранения сведений об адресе узла. Структура addrinfoex — это расширенная версия структур addrinfo и addrinfoW. Дополнительные члены структуры предназначены для данных BLOB-объектов и GUID для поставщика пространства имен. Данные большого двоичного объекта используются для возврата дополнительных сведений о пространстве имен для конкретного поставщика, связанных с именем. Формат данных в элементе ai_blob зависит от конкретного поставщика пространства имен. В настоящее время данные BLOB-объектов используются поставщиком пространства имен NS_EMAIL для предоставления дополнительных сведений.

Структура addrinfoex — это расширенная версия addrinfo и структура addrinfoW, используемая с функцией GetAddrInfoEx. Функция GetAddrInfoEx позволяет указать поставщика пространства имен для разрешения запроса. Для использования с протоколом IPv6 и IPv4 разрешение имен может быть системой доменных имен (DNS), локальным узлами файла, поставщиком электронной почты (пространством имен NS_EMAIL) или другими механизмами именования.

При определении ЮНИКОДа или _UNICODE addrinfoex определяется как addrinfoexW, версия Юникода этой структуры. Строковые параметры определяются для типа данных PWSTR и используется структура addrinfoexW.

Если юникод или _UNICODE не определен, addrinfoex определяется как addrinfoexA, версия ANSI этой структуры. Строковые параметры относятся к типу данных PCSTR и используется структура addrinfoexA.

После успешного вызова GetAddrInfoExсвязанный список структур addrinfoex возвращается в параметре ppResult, переданном функции GetAddrInfoEx. Список можно обрабатывать, следуя указателю, указанному в элементе ai_next каждого возвращаемого надстройки addrinfoex, пока не будет обнаружен указатель NULL. В каждой возвраща емой структуре addrinfoexai_family, ai_socktypeи ai_protocol члены соответствуют соответствующим аргументам в сокетеили вызове функции WSASocket. Кроме того, элемент ai_addr в каждом возвращенном addrinfoex указывает на структуру адресов сокета, длину которой указывается в его ai_addrlen члене.

Примеры

В следующем примере показано использование структуры addrinfoex.


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

    ADDRINFOEX *result = NULL;
    ADDRINFOEX *ptr = NULL;
    ADDRINFOEX hints;

    DWORD dwRetval = 0;
    int i = 1;

    DWORD dwNamespace = NS_DNS;
    LPGUID lpNspid = NULL;

    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 GetAddrInfoEx with following parameters:\n");
    wprintf(L"\tName = %ws\n", argv[1]);
    wprintf(L"\tServiceName (or port) = %ws\n\n", argv[2]);

//--------------------------------
// Call GetAddrInfoEx(). If the call succeeds,
// the aiList variable will hold a linked list
// of ADDRINFOEX structures containing response
// information about the host
    dwRetval = GetAddrInfoEx(argv[1], argv[2],
                             dwNamespace, lpNspid, &hints, &result,
                             NULL, NULL, NULL, NULL);

    if (dwRetval != 0) {
        wprintf(L"GetAddrInfoEx failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }
    wprintf(L"GetAddrInfoEx returned success\n");

    // Retrieve each address and print out the hex bytes
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {

        wprintf(L"GetAddrInfoEx 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);
    }

    FreeAddrInfoEx(result);
    WSACleanup();

    return 0;
}


Примечание Убедитесь, что среда разработки ориентирована на новую версию Ws2tcpip.h, которая включает определения структуры и функций для ADDRINFOEX и GetAddrInfoExсоответственно.
 

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows Vista [только классические приложения]
минимальный поддерживаемый сервер Windows Server 2008 [только классические приложения]
заголовка ws2def.h (включая Windows Server 2012, Windows 7 Windows Server 2008 R2)

См. также

GetAddrInfoEx

addrinfo

addrinfoW