Функция 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

Указатель на строку ANSI, завершающуюся null, которая содержит имя узла (узла) или строку числового адреса узла. Для интернет-протокола строка числового адреса узла представляет собой IPv4-адрес с точками или шестнадцатеричный IPv6-адрес.

[in, optional] pServiceName

Указатель на строку ANSI, завершающуюся значением NULL, которая содержит имя службы или номер порта, представленный в виде строки.

Имя службы — это строковый псевдоним для номера порта. Например, "http" — это псевдоним порта 80, определенный целевой группой по проектированию в Интернете (IETF) в качестве порта по умолчанию, используемого веб-серверами для протокола HTTP. Возможные значения параметра pServiceName , если номер порта не указан, перечислены в следующем файле:

%WINDIR%\system32\drivers\etc\services

[in, optional] pHints

Указатель на структуру addrinfo , которая предоставляет указания о типе сокета, который поддерживает вызывающий объект.

Элементы ai_addrlen, ai_canonname, ai_addr и ai_next структуры addrinfo , на которую указывает параметр pHints , должны иметь значение null или NULL. В противном случае функция GetAddrInfoEx завершится сбоем с WSANO_RECOVERY.

Дополнительные сведения см. в разделе Примечания.

[out] ppResult

Указатель на связанный список одной или нескольких структур addrinfo , содержащих сведения об ответе об узле.

Возвращаемое значение

При успешном выполнении возвращается ноль. Сбой возвращает ненулевой код ошибки Сокеты Windows, как указано в разделе Коды ошибок сокетов Windows.

Большинство ненулевых кодов ошибок, возвращаемых функцией getaddrinfo , сопоставляются с набором ошибок, описанных в рекомендациях Internet Engineering Task Force (IETF). В следующей таблице перечислены эти коды ошибок и их эквиваленты WSA. Рекомендуется использовать коды ошибок WSA, так как они предоставляют знакомые и исчерпывающие сведения об ошибках для программистов Winsock.

Значение ошибки Эквивалент WSA Описание
EAI_AGAIN WSATRY_AGAIN Произошел временный сбой при разрешении имен.
EAI_BADFLAGS WSAEINVAL Для элемента ai_flags параметра pHints указано недопустимое значение.
EAI_FAIL WSANO_RECOVERY Произошел неустранимый сбой при разрешении имен.
EAI_FAMILY WSAEAFNOSUPPORT Элемент ai_family параметра pHints не поддерживается.
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY Произошел сбой выделения памяти.
EAI_NONAME WSAHOST_NOT_FOUND Имя не разрешается для указанных параметров или параметры pNodeName и pServiceName не указаны.
EAI_SERVICE WSATYPE_NOT_FOUND Параметр pServiceName не поддерживается для указанного элемента ai_socktype параметра pHints .
EAI_SOCKTYPE WSAESOCKTNOSUPPORT Элемент ai_socktype параметра pHints не поддерживается.
 

Используйте функцию gai_strerror для вывода сообщений об ошибках на основе кодов EAI, возвращаемых функцией getaddrinfo . Функция gai_strerror предоставляется для соответствия рекомендациям IETF, но не является потокобезопасной. Поэтому рекомендуется использовать традиционные функции сокетов Windows, такие как WSAGetLastError .

Код ошибки Значение
WSA_NOT_ENOUGH_MEMORY
Недостаточно памяти для выполнения операции.
WSAEAFNOSUPPORT
Использовался адрес, несовместимый с запрошенным протоколом. Эта ошибка возвращается, если ai_family член структуры addrinfo, на которую указывает параметр pHints , не поддерживается.
WSAEINVAL
Указан недопустимый аргумент. Эта ошибка возвращается, если для ai_flags члена структуры addrinfo , на которую указывает параметр pHints , было предоставлено недопустимое значение.
WSAESOCKTNOSUPPORT
Указанный тип сокета не поддерживается в данном семействе адресов. Эта ошибка возвращается, если ai_socktype член структуры addrinfo, на которую указывает параметр pHints , не поддерживается.
WSAHOST_NOT_FOUND
Такой узел не существует. Эта ошибка возвращается, если имя не разрешается для предоставленных параметров или параметры pNodeName и pServiceName не указаны.
WSANO_DATA
Запрошенное имя является допустимым, но данные запрошенного типа не найдены.
WSANO_RECOVERY
При просмотре базы данных произошла неустранимая ошибка. Эта ошибка возвращается, если произошла неустранимая ошибка при разрешении имен.
WSANOTINITIALISED
Перед использованием этой функции должен произойти успешный вызов WSAStartup .
WSATRY_AGAIN
Обычно это временная ошибка при разрешении имени узла, и она означает, что локальный сервер не получил ответа от заслуживающего доверия сервера. Эта ошибка возвращается при временном сбое разрешения имен.
WSATYPE_NOT_FOUND
Указанный класс не найден. Параметр pServiceName не поддерживается для указанного элемента ai_socktype структуры addrinfo, на которую указывает параметр pHints .

Комментарии

Функция getaddrinfo — это версия ANSI функции, которая обеспечивает независимый от протокола перевод из имени узла в адрес. Версия Этой функции в Юникоде — GetAddrInfoW. Разработчикам рекомендуется использовать функцию Юникода GetAddrInfoW , а не функцию getaddrinfo ANSI.

Функция getaddrinfo возвращает результаты для пространства имен NS_DNS . Функция getaddrinfo объединяет все ответы, если несколько поставщиков пространств имен возвращают сведения. Для использования с протоколами IPv6 и IPv4 разрешение имен может осуществляться системой доменных имен (DNS), локальным файлом узлов или другими механизмами именования для пространства имен NS_DNS .

Другое имя, которое можно использовать для функции getaddrinfo , — GetAddrInfoA. Макросы в файле заголовка Ws2tcpip.h определяют GetAddrInfoA для getaddrinfo.

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

Имена и типы параметров для функции getaddrinfo , определенные в файле заголовка Ws2tcpip.h пакета SDK для Windows Server 2003 и Windows XP, отличались.

Один или оба параметра pNodeName или pServiceName должны указывать на строку ANSI, завершаемую null; Как правило, предоставляются оба варианта.

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

Если параметр pNodeName указывает на имя компьютера, возвращаются все постоянные адреса компьютера, которые можно использовать в качестве исходного адреса. В Windows Vista и более поздних версиях эти адреса будут включать все одноадресные IP-адреса, возвращаемые функциями GetUnicastIpAddressTable или GetUnicastIpAddressEntry , в которых член SkipAsSource имеет значение false в структуре MIB_UNICASTIPADDRESS_ROW .

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

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

В Windows Server 2003 и более поздних версиях, если параметр pNodeName указывает на строку, равную ". localmachine", возвращаются все зарегистрированные адреса на локальном компьютере.

Если параметр pNodeName ссылается на имя виртуального сервера кластера, возвращаются только адреса виртуальных серверов. В Windows Vista и более поздних версиях эти адреса будут включать все одноадресные IP-адреса, возвращаемые функциями GetUnicastIpAddressTable или GetUnicastIpAddressEntry , в которых член SkipAsSource имеет значение true в структуре MIB_UNICASTIPADDRESS_ROW . Дополнительные сведения о кластеризация см. в разделе Кластеризация Windows.

Windows 7 с пакетом обновления 1 (SP1) и Windows Server 2008 R2 с пакетом обновления 1 (SP1) поддерживают Netsh.exe для настройки атрибута SkipAsSource для IP-адреса. Это также изменяет поведение таким образом, что если член SkipAsSource в структуре MIB_UNICASTIPADDRESS_ROW имеет значение false, IP-адрес будет зарегистрирован в DNS. Если для элемента SkipAsSource задано значение true, IP-адрес не регистрируется в DNS.

Доступно исправление для Windows 7 и Windows Server 2008 R2, которое добавляет поддержку Netsh.exe для задания атрибута SkipAsSource для IP-адреса. Это исправление также изменяет поведение таким образом, что если член SkipAsSource в структуре MIB_UNICASTIPADDRESS_ROW имеет значение false, IP-адрес будет зарегистрирован в DNS. Если для элемента SkipAsSource задано значение true, IP-адрес не регистрируется в DNS. Дополнительные сведения см. в 2386184 базы знаний .

Аналогичное исправление также доступно для Windows Vista с пакетом обновления 2 (SP2) и Windows Server 2008 с пакетом обновления 2 (SP2), которое добавляет поддержку Netsh.exe для задания атрибута SkipAsSource в IP-адресе. Это исправление также изменяет поведение таким образом, что если член SkipAsSource в структуре MIB_UNICASTIPADDRESS_ROW имеет значение false, IP-адрес будет зарегистрирован в DNS. Если для элемента SkipAsSource задано значение true, IP-адрес не регистрируется в DNS.

Вызывающие функции getaddrinfo могут предоставлять подсказки о поддерживаемом типе сокета с помощью структуры addrinfo, на которую указывает параметр pHints . При использовании параметра pHints к связанной структуре addrinfo применяются следующие правила:

  • Значение AF_UNSPEC для ai_family указывает, что вызывающий объект будет принимать только семейства AF_INET и AF_INET6 адресов. Обратите внимание, что AF_UNSPEC и PF_UNSPEC одинаковы.
  • Нулевое значение для ai_socktype указывает, что вызывающий объект будет принимать любой тип сокета.
  • Нулевое значение для ai_protocol указывает, что вызывающий объект будет принимать любой протокол.
  • Элемент ai_addrlen должен иметь нулевое значение.
  • Элемент ai_canonname должен иметь значение NULL.
  • Элемент ai_addr должен иметь значение NULL.
  • Элемент ai_next должен иметь значение NULL.

Значение AF_UNSPEC для ai_family указывает, что вызывающий объект будет принимать любое семейство протоколов. Это значение можно использовать для возврата адресов IPv4 и IPv6 для имени узла, на которое указывает параметр pNodeName . В Windows Server 2003 и Windows XP адреса IPv6 возвращаются только в том случае, если на локальном компьютере установлен протокол IPv6.

Другие значения в структуре addrinfo , предоставленной в параметре pHints, указывают на определенные требования. Например, если вызывающий объект обрабатывает только протокол IPv4 и не обрабатывает IPv6, для элемента ai_family должно быть задано значение AF_INET. Другой пример: если вызывающий объект обрабатывает только TCP и не обрабатывает UDP, для элемента ai_socktype должно быть задано значение SOCK_STREAM.

Если параметр pHints является указателем NULL , функция getaddrinfo обрабатывает его так, как если бы структура addrinfo в pHints была инициализирована с ее ai_family элементом, заданным AF_UNSPEC , а все остальные члены равны нулю.

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

Функцию getaddrinfo можно использовать для преобразования текстового строкового представления IP-адреса в структуру addrinfo , содержащую структуру sockaddr для IP-адреса и других сведений. Для использования таким образом строка, на которую указывает параметр pNodeName , должна содержать текстовое представление IP-адреса, а структура addrinfo, на которую указывает параметр pHints , должна иметь флаг AI_NUMERICHOST, установленный в элементе ai_flags . Строка, на которую указывает параметр pNodeName , может содержать текстовое представление адреса IPv4 или IPv6. Текстовый IP-адрес преобразуется в структуру addrinfo , на которую указывает параметр ppResult . Возвращаемая структура addrinfo содержит структуру sockaddr для IP-адреса, а также дополнительные сведения об IP-адресе. Чтобы этот метод работал со строкой IPv6-адреса в Windows Server 2003 и Windows XP, на локальном компьютере должен быть установлен протокол IPv6. В противном случае возвращается ошибка WSAHOST_NOT_FOUND .

Освобождение сведений об адресе от динамического выделения

Вся информация, возвращаемая функцией getaddrinfo , на которую указывает параметр ppResult , выделяется динамически, включая все структуры 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 , которая включает определения структуры и функций для addrinfo и getaddrinfo соответственно.
 

Международные доменные имена

Имена узлов Интернета обычно состоят из очень ограниченного набора символов:
  • буквы верхнего и нижнего регистра английского алфавита в кодировке ASCII;
  • цифры от 0 до 9;
  • Символы дефиса ASCII.

С ростом интернета возрастает потребность в определении имен узлов в Интернете для других языков, не представленных набором символов ASCII. Идентификаторы, которые упрощают эту потребность и позволяют представить символы, отличные от ASCII (Юникод), в виде специальных строк символов ASCII, называются интернационализированными доменными именами (IDN). Для стандартной обработки IDN используется механизм интернационализации доменных имен в приложениях (IDNA). Спецификации idn и IDNA задокументированы в документах RFC 3490, RTF 5890 и RFC 6365 , опубликованных Целевой службой разработки интернета (IETF).

На Windows 8 и Windows Server 2012 функция getaddrinfo обеспечивает поддержку синтаксического анализа международного доменного имени (IDN), применяемого к имени, переданного в параметре pNodeName. Winsock выполняет кодирование и преобразование punycode/IDN. Это поведение можно отключить с помощью флага AI_DISABLE_IDN_ENCODING , описанного ниже.

В Windows 7 и Windows Server 2008 R2 или более ранних версиях функция getaddrinfo в настоящее время не поддерживает синтаксический анализ idNn, применяемый к имени, переданного в параметре pNodeName . Winsock не выполняет преобразование Punycode/IDN. Версия расширенных символов функции GetAddrInfo не использует Punycode для преобразования IDN в формате RFC 3490. Версия расширенных символов функции GetAddrInfo при запросе DNS кодирует имя Юникода в формате UTF-8, который используется DNS-серверами Майкрософт в корпоративной среде.

Некоторые функции в Windows Vista и более поздних версиях поддерживают преобразование меток Юникода в idN в их эквиваленты ASCII. Итоговое представление каждой метки Юникода содержит только символы ASCII и начинается с префикса xn--, если метка Юникода содержит символы, отличные от ASCII. Причина заключается в поддержке существующих DNS-серверов в Интернете, так как некоторые средства и серверы DNS поддерживают только символы ASCII (см. RFC 3490).

Функция IdnToAscii использует Punycode для преобразования IDN в представление ASCII исходной строки Юникода с помощью стандартного алгоритма, определенного в RFC 3490. Функция IdnToUnicode преобразует asCII-форму IDN в обычный синтаксис кодировки Юникод UTF-16. Дополнительные сведения и ссылки на соответствующие проекты стандартов см. в разделе Обработка международных доменных имен (IDN).

Функцию IdnToAscii можно использовать для преобразования имени IDN в форму ASCII, которую затем можно передать в параметре pNodeName в функцию getaddrinfo . Чтобы передать это имя IDN в функцию GetAddrInfo при использовании версии расширенных символов этой функции (при определении ЮНИКОДа или _UNICODE), можно использовать функцию MultiByteToWideChar для преобразования строки CHAR в строку WCHAR .

Использование ai_flags в параметре pHints

Флаги в ai_flags элементе необязательной структуры addrinfo , предоставленной в параметре pHints, изменяют поведение функции.

Эти биты флагов определены в файле заголовка Ws2def.h на microsoft пакет средств разработки программного обеспечения для Windows (SDK) для Windows 7. Эти биты флагов определены в файле заголовка Ws2tcpip.h в Windows SDK для Windows Server 2008 и Windows Vista. Эти биты флагов определены в файле заголовка Ws2tcpip.h в пакете SDK платформы для Windows Server 2003 и Windows XP.

Биты флага могут быть комбинацией следующих:

Биты флага Описание
AI_PASSIVE Установка флага AI_PASSIVE указывает, что вызывающий объект намерен использовать возвращенную структуру адреса сокета при вызове функции bind . Если флаг AI_PASSIVE установлен, а pNodeName является указателем NULL , для части IP-адреса структуры адресов сокета устанавливается значение INADDR_ANY для IPv4-адресов и IN6ADDR_ANY_INIT для IPv6-адресов.

Если флаг AI_PASSIVE не установлен, то возвращаемая структура адресов сокета готова к вызову функции connect для протокола, ориентированного на подключение, или к вызову функций connect, sendto или send для протокола без подключения. Если параметр pNodeName в данном случае является указателем NULL , для части IP-адреса структуры адресов сокета устанавливается адрес замыкания на себя.

AI_CANONNAME Если ни AI_CANONNAME , ни AI_NUMERICHOST не используются, функция getaddrinfo пытается разрешить. Если передается строка литерала , getaddrinfo пытается преобразовать строку, а если передается имя узла, функция getaddrinfo пытается разрешить имя в адрес или несколько адресов.

Если задан бит AI_CANONNAME , параметр pNodeName не может иметь значение NULL. В противном случае функция getaddrinfo завершится сбоем с WSANO_RECOVERY.

Если задан бит AI_CANONNAME и функция getaddrinfo возвращает успешное выполнение, член ai_canonname в параметре ppResult указывает на строку с завершением NULL, содержащую каноническое имя указанного узла.

Примечание Функция getaddrinfo может возвращать успешное выполнение, если установлен флаг AI_CANONNAME , но элемент ai_canonname в связанной структуре addrinfo имеет значение NULL. Поэтому рекомендуемое использование флага AI_CANONNAME включает проверку того, имеет ли член ai_canonname в связанной структуре addrinfoзначение NULL.
 
AI_NUMERICHOST Если задан бит AI_NUMERICHOST, параметр pNodeName должен содержать строку ненулевого числового адреса узла, в противном случае возвращается ошибка EAI_NONAME. Этот флаг предотвращает вызов службы разрешения имен.
AI_NUMERICSERV Если задан бит AI_NUMERICSERV , параметр pServiceName должен содержать числовой номер порта, отличный от NULL , в противном случае возвращается ошибка EAI_NONAME . Этот флаг предотвращает вызов службы разрешения имен.

Флаг AI_NUMERICSERV определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_NUMERICSERV не поддерживается поставщиками Майкрософт.

AI_ALL Если задан бит AI_ALL , выполняется запрос на IPv6-адреса и IPv4-адреса с AI_V4MAPPED.

Флаг AI_ALL определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_ALL поддерживается в Windows Vista и более поздних версиях.

AI_ADDRCONFIG Если задан бит AI_ADDRCONFIG , getaddrinfo будет разрешаться только в том случае, если настроен глобальный адрес. Если указан флаг AI_ADDRCONFIG , IPv4-адреса должны возвращаться только в том случае, если адрес IPv4 настроен в локальной системе, а адреса IPv6 должны возвращаться только в том случае, если адрес IPv6 настроен в локальной системе. Адрес замыкания на себя IPv4 или IPv6 не считается допустимым глобальным адресом.

Флаг AI_ADDRCONFIG определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_ADDRCONFIG поддерживается в Windows Vista и более поздних версиях.

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

Флаг AI_V4MAPPED определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_V4MAPPED поддерживается в Windows Vista и более поздних версиях.

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

Флаг AI_NON_AUTHORITATIVE определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_NON_AUTHORITATIVE поддерживается в Windows Vista и более поздних версиях и применяется только к пространству имен NS_EMAIL .

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

Флаг AI_SECURE определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_SECURE поддерживается в Windows Vista и более поздних версиях и применяется только к пространству имен NS_EMAIL .

AI_RETURN_PREFERRED_NAMES Если задано AI_RETURN_PREFERRED_NAMES , в параметре pNodeName не следует указать имя. Поставщик пространства имен NS_EMAIL вернет предпочтительные имена для публикации.

Флаг AI_RETURN_PREFERRED_NAMES определен в Windows SDK для Windows Vista и более поздних версий. Флаг AI_RETURN_PREFERRED_NAMES поддерживается в Windows Vista и более поздних версиях и применяется только к пространству имен NS_EMAIL .

AI_FQDN Если задано AI_FQDN и указано неструктурированное имя (одна метка), getaddrinfo вернет полное доменное имя, в которое в конечном итоге будет разрешено имя. Полное доменное имя возвращается в элементе ai_canonname в связанной структуре addrinfo . Это отличается от AI_CANONNAME битового флага, возвращающего каноническое имя, зарегистрированное в DNS, которое может отличаться от полного доменного имени, в которое разрешается неструктурированное имя. Можно задать только один из битов AI_FQDN и AI_CANONNAME . Функция getaddrinfo завершится ошибкой, если оба флага присутствуют с EAI_BADFLAGS.

Если задан бит AI_FQDN , параметр pNodeName не может иметь значение NULL. В противном случае функция GetAddrInfoEx завершится сбоем с WSANO_RECOVERY.

Windows 7: Флаг AI_FQDN определен в Windows SDK для Windows 7 и более поздних версий. Флаг AI_FQDN поддерживается в Windows 7 и более поздних версиях.

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

Windows 7: Флаг AI_FILESERVER определен в Windows SDK для Windows 7 и более поздних версий. Флаг AI_FILESERVER поддерживается в Windows 7 и более поздних версиях.

 

Пример кода с использованием AI_NUMERICHOST

В следующем примере кода показано, как использовать функцию getaddrinfo для преобразования текстового строкового представления IP-адреса в структуру addrinfo , содержащую структуру sockaddr для IP-адреса и других сведений.
#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;
}

Поддержка getaddrinfo в Windows 2000 и более ранних версиях

Функция getaddrinfo была добавлена в Ws2_32.dll в Windows XP и более поздних версий. Чтобы выполнить приложение, использующее эту функцию в более ранних версиях Windows, необходимо включить файлы 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 — это версия getaddrinfo в Юникоде. Функция GetAddrInfoW была добавлена в Ws2_32.dll в Windows XP с пакетом обновления 2 (SP2). Функцию GetAddrInfoW нельзя использовать в версиях Windows, предшествующих Windows XP с пакетом обновления 2 (SP2).

Windows Phone 8. Эта функция поддерживается для приложений Магазина Windows Phone Windows Phone 8 и более поздних версий.

Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows в Windows 8.1, Windows Server 2012 R2 и более поздних версий.

Требования

Требование Значение
Минимальная версия клиента Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header 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

Сокета