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


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

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

Синтаксис

typedef struct addrinfo {
  int             ai_flags;
  int             ai_family;
  int             ai_socktype;
  int             ai_protocol;
  size_t          ai_addrlen;
  char            *ai_canonname;
  struct sockaddr *ai_addr;
  struct addrinfo *ai_next;
} ADDRINFOA, *PADDRINFOA;

Члены

ai_flags

Тип: int

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

Поддерживаемые значения элемента ai_flags определяются в файле заголовка Ws2def.h на Windows SDK для Windows 7 и более поздних версий. Эти значения определены в файле заголовка Ws2tcpip.h в Windows SDK для Windows Server 2008 и Windows Vista. Эти значения определены в файле заголовка Ws2tcpip.h в пакете SDK платформы для Windows Server 2003 и Windows XP. Поддерживаемые значения для элемента ai_flags могут быть комбинацией следующих параметров.

Значение Значение
AI_PASSIVE
0x01
Адрес сокета будет использоваться при вызове функции bind .
AI_CANONNAME
0x02
Каноническое имя возвращается в первом элементе ai_canonname .
AI_NUMERICHOST
0x04
Параметр nodename , передаваемый в функцию getaddrinfo , должен быть числовой строкой.
AI_ALL
0x0100
Если этот бит задан, выполняется запрос на адреса IPv6 и IPv4 с AI_V4MAPPED.

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

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

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

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

Этот параметр поддерживается в 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
Если указано неструктурированное имя (одна метка), getaddrinfo вернет полное доменное имя, в которое в конечном итоге будет разрешено имя. Полное доменное имя возвращается в члене ai_canonname .

Это отличается от AI_CANONNAME битового флага, возвращающего каноническое имя, зарегистрированное в DNS, которое может отличаться от полного доменного имени, в которое разрешается неструктурированное имя.

Можно задать только один из битов AI_FQDN и AI_CANONNAME . Функция getaddrinfo завершится ошибкой, если оба флага присутствуют с EAI_BADFLAGS.

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

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

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

ai_family

Тип: int

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

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

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

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

Значение Значение
AF_UNSPEC
0
Семейство адресов не указано.
AF_INET
2
Семейство адресов IPv4.
AF_NETBIOS
17
Семейство адресов NetBIOS. Это семейство адресов поддерживается только в том случае, если установлен поставщик Сокетов Windows для NetBIOS.
AF_INET6
23
Семейство адресов 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_familyявляется AF_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 Sockets 1.1 единственными возможными типами сокетов являются SOCK_DATAGRAM и SOCK_STREAM.

ai_protocol

Тип: int

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

На Windows SDK, выпущенном для Windows Vista и более поздних версий, организация файлов заголовков изменилась, и этот член может быть одним из значений из типа перечисления IPPROTO, определенного в файле заголовка 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 , а параметр typeSOCK_DGRAM.
IPPROTO_RM
113
Протокол PGM для надежной многоадресной рассылки. Это возможное значение, если элемент ai_familyAF_INET , а элемент ai_socktype— SOCK_RDM. На Windows SDK, выпущенном для Windows Vista и более поздних версий, это значение также называется IPPROTO_PGM.
 

Если элемент ai_familyAF_IRDA, то ai_protocol должен иметь значение 0.

ai_addrlen

Тип: size_t

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

ai_canonname

Тип: char*

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

ai_addr

Тип: struct sockaddr*

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

ai_next

Тип: struct addrinfo*

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

Комментарии

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

Структура addrinfoW — это версия этой структуры, используемая функцией GetAddrInfoW в Юникоде.

Макросы в файле заголовка Ws2tcpip.h определяют структуру ADDRINFOT и имя функции GetAddrInfo в смешанном регистре. Функция GetAddrInfo должна вызываться с параметрами nodename и servname указателя типа TCHAR , а также указаниями и параметрами res указателя типа ADDRINFOT. Если юникод или _UNICODE не определены, addRINFOT определяется в структуре addrinfo , а GetAddrInfo — для getaddrinfo, версии ANSI этой функции. При определении ЮНИКОДа или _UNICODE функция ADDRINFOT определяется для структуры addrinfoW , а GetAddrInfo — для GetAddrInfoW, версии этой функции в Юникоде.

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

Поддержка getaddrinfo и структуры addrinfo в более ранних версиях Windows

Функция getaddrinfo , использующая структуру addrinfo , была добавлена в Ws2_32.dll в Windows XP и более поздних версий. Структура addrinfo определена в файле заголовка Ws2tcpip.h, который входит в состав пакета SDK для платформы, выпущенного для Windows XP и более поздних версий, а также в Windows SDK для Windows Vista и более поздних версий.

Чтобы выполнить приложение, использующее функцию getaddrinfo и структуру addrinfo в более ранних версиях Windows (Windows 2000), необходимо включить файлы Ws2tcpip.h и Wspiapi.h . При добавлении включаемого файла Wspiapi.h функция getaddrinfo определяется для встроенной функции WspiapiGetAddrInfo в файле Wspiapi.h . Во время выполнения функция WspiapiGetAddrInfo реализована таким образом, что если Ws2_32.dll или Wship6.dll (файл, содержащий getaddrinfo в предварительной версии технологии IPv6 для Windows 2000) не включает getaddrinfo, то версия getaddrinfo реализована на основе кода в файле заголовка Wspiapi.h . Этот встроенный код будет использоваться на старых платформах Windows, которые изначально не поддерживают функцию getaddrinfo .

Протокол IPv6 поддерживается в Windows 2000 при установке предварительной версии технологии IPv6 для Windows 2000. В противном случае поддержка getaddrinfo в версиях Windows, предшествующих Windows XP, ограничена обработкой разрешения имен IPv4.

Функция GetAddrInfoW , использующая структуру addrinfoW , является версией функции getaddrinfo в Юникоде и связанной структурой addrinfo . Функция GetAddrInfoW была добавлена в Ws2_32.dll в Windows XP с пакетом обновления 2 (SP2). Функцию GetAddrInfoW и структуру addrinfoW нельзя использовать в версиях Windows, предшествующих Windows XP с пакетом обновления 2 (SP2).

Примеры

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


#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("       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;
}

Требования

Требование Значение
Минимальная версия клиента Windows 2000 Professional [только классические приложения]
Минимальная версия сервера Windows 2000 Server [только классические приложения]
Верхняя часть ws2def.h

См. также раздел

GetAddrInfoW

WSAEnumProtocols

addrinfoW

bind

getaddrinfo

sockaddr