Função getaddrinfo (ws2tcpip.h)

A função getaddrinfo fornece tradução independente de protocolo de um nome de host ANSI para um endereço.

Sintaxe

INT WSAAPI getaddrinfo(
  [in, optional] PCSTR           pNodeName,
  [in, optional] PCSTR           pServiceName,
  [in, optional] const ADDRINFOA *pHints,
  [out]          PADDRINFOA      *ppResult
);

Parâmetros

[in, optional] pNodeName

Um ponteiro para uma cadeia de caracteres ANSI terminada em NULL que contém um nome de host (nó) ou uma cadeia de caracteres de endereço de host numérico. Para o protocolo da Internet, a cadeia de caracteres de endereço de host numérico é um endereço IPv4 decimal pontilhado ou um endereço hexadecimal IPv6.

[in, optional] pServiceName

Um ponteiro para uma cadeia de caracteres ANSI terminada em NULL que contém um nome de serviço ou um número de porta representado como uma cadeia de caracteres.

Um nome de serviço é um alias de cadeia de caracteres para um número de porta. Por exemplo, "http" é um alias para a porta 80 definido pela IETF (Internet Engineering Task Force) como a porta padrão usada pelos servidores Web para o protocolo HTTP. Os valores possíveis para o parâmetro pServiceName quando um número de porta não é especificado são listados no seguinte arquivo:

%WINDIR%\system32\drivers\etc\services

[in, optional] pHints

Um ponteiro para uma estrutura addrinfo que fornece dicas sobre o tipo de soquete ao qual o chamador dá suporte.

Os membros ai_addrlen, ai_canonname, ai_addr e ai_next da estrutura addrinfo apontada pelo parâmetro pHints devem ser zero ou NULL. Caso contrário, a função GetAddrInfoEx falhará com WSANO_RECOVERY.

Consulte os Comentários para obter mais detalhes.

[out] ppResult

Um ponteiro para uma lista vinculada de uma ou mais estruturas addrinfo que contém informações de resposta sobre o host.

Retornar valor

Êxito retorna zero. Falha retorna um código de erro diferente de zero do Windows Sockets, conforme encontrado nos Códigos de Erro do Windows Sockets.

A maioria dos códigos de erro diferentes de zero retornados pelo mapa de funções getaddrinfo para o conjunto de erros descrito pelas recomendações da IETF (Internet Engineering Task Force). A tabela a seguir lista esses códigos de erro e seus equivalentes do WSA. É recomendável que os códigos de erro do WSA sejam usados, pois oferecem informações de erro familiares e abrangentes para programadores Winsock.

Valor do erro Equivalente a WSA Descrição
EAI_AGAIN WSATRY_AGAIN Ocorreu uma falha temporária na resolução de nomes.
EAI_BADFLAGS WSAEINVAL Um valor inválido foi fornecido para o membro ai_flags do parâmetro pHints .
EAI_FAIL WSANO_RECOVERY Ocorreu uma falha não recuperável na resolução de nomes.
EAI_FAMILY WSAEAFNOSUPPORT Não há suporte para o membro ai_family do parâmetro pHints .
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY Ocorreu uma falha de alocação de memória.
EAI_NONAME WSAHOST_NOT_FOUND O nome não resolve para os parâmetros fornecidos ou os parâmetros pNodeName e pServiceName não foram fornecidos.
EAI_SERVICE WSATYPE_NOT_FOUND Não há suporte para o parâmetro pServiceName para o membro ai_socktype especificado do parâmetro pHints .
EAI_SOCKTYPE WSAESOCKTNOSUPPORT Não há suporte para o membro ai_socktype do parâmetro pHints .
 

Use a função gai_strerror para imprimir mensagens de erro com base nos códigos EAI retornados pela função getaddrinfo . A função gai_strerror é fornecida para conformidade com as recomendações de IETF, mas não é thread-safe. Portanto, o uso de funções tradicionais do Windows Sockets, como WSAGetLastError , é recomendado.

Código do erro Significado
WSA_NOT_ENOUGH_MEMORY
Não havia memória suficiente para executar a operação.
WSAEAFNOSUPPORT
Um endereço incompatível com o protocolo solicitado foi usado. Esse erro será retornado se não houver suporte para o membro ai_family da estrutura addrinfo apontada pelo parâmetro pHints .
WSAEINVAL
Foi fornecido um argumento inválido. Esse erro será retornado se um valor inválido tiver sido fornecido para o membro ai_flags da estrutura addrinfo apontada pelo parâmetro pHints .
WSAESOCKTNOSUPPORT
O suporte para o tipo de soquete especificado não existe nessa família de endereços. Esse erro será retornado se não houver suporte para o membro ai_socktype da estrutura addrinfo apontada pelo parâmetro pHints .
WSAHOST_NOT_FOUND
Esse host não é conhecido. Esse erro será retornado se o nome não resolve para os parâmetros fornecidos ou os parâmetros pNodeName e pServiceName não foram fornecidos.
WSANO_DATA
O nome solicitado é válido, mas nenhum dado do tipo solicitado foi encontrado.
WSANO_RECOVERY
Ocorreu um erro irrecuperável durante uma pesquisa no banco de dados. Esse erro será retornado se ocorrer um erro não recuperável na resolução de nomes.
WSANOTINITIALISED
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função.
WSATRY_AGAIN
Esse é geralmente um erro temporário durante a resolução do nome do host e significa que o servidor local não recebeu uma resposta de um servidor autorizado. Esse erro é retornado quando ocorreu uma falha temporária na resolução de nomes.
WSATYPE_NOT_FOUND
A classe especificada não foi encontrada. Não há suporte para o parâmetro pServiceName para o membro ai_socktype especificado da estrutura addrinfo apontada pelo parâmetro pHints .

Comentários

A função getaddrinfo é a versão ANSI de uma função que fornece tradução independente de protocolo do nome do host para o endereço. A versão Unicode dessa função é GetAddrInfoW. Os desenvolvedores são incentivados a usar a função Unicode GetAddrInfoW em vez da função ANSI getaddrinfo .

A função getaddrinfo retorna resultados para o namespace NS_DNS . A função getaddrinfo agrega todas as respostas se mais de um provedor de namespace retornar informações. Para uso com o protocolo IPv6 e IPv4, a resolução de nomes pode ser pelo DNS (Sistema de Nomes de Domínio), um arquivo de hosts local ou por outros mecanismos de nomenclatura para o namespace NS_DNS .

Outro nome que pode ser usado para a função getaddrinfo é GetAddrInfoA. Macros no arquivo de cabeçalho Ws2tcpip.h definem GetAddrInfoA como getaddrinfo.

Macros no arquivo de cabeçalho Ws2tcpip.h definem um nome de função de maiúsculas e minúsculas de GetAddrInfo e uma estrutura ADDRINFOT . Essa função GetAddrInfo deve ser chamada com os parâmetros pNodeName e pServiceName de um ponteiro do tipo TCHAR e os parâmetros pHints e ppResult de um ponteiro do tipo ADDRINFOT. Quando UNICODE ou _UNICODE não está definido, GetAddrInfo é definido como getaddrinfo, a versão ANSI da função e ADDRINFOT é definido para a estrutura addrinfo . Quando UNICODE ou _UNICODE é definido, GetAddrInfo é definido como GetAddrInfoW, a versão Unicode da função e ADDRINFOT é definido para a estrutura addrinfoW .

Os nomes de parâmetro e os tipos de parâmetro para a função getaddrinfo definida no arquivo de cabeçalho Ws2tcpip.h no SDK (Platform Software Development Kit) para Windows Server 2003 e Windows XP eram diferentes.

Um ou ambos os parâmetros pNodeName ou pServiceName devem apontar para uma cadeia de caracteres ANSI terminada em NULL; geralmente, ambos são fornecidos.

Após o êxito, uma lista vinculada de estruturas addrinfo é retornada no parâmetro ppResult . A lista pode ser processada seguindo o ponteiro fornecido no membro ai_next de cada estrutura addrinfo retornada até que um ponteiro NULL seja encontrado. Em cada estrutura addrinfo retornada, os membros ai_family, ai_socktype e ai_protocol correspondem aos respectivos argumentos em uma chamada de função de soquete ou WSASocket . Além disso, o membro ai_addr em cada estrutura addrinfo retornada aponta para uma estrutura de endereço de soquete preenchida, cujo comprimento é especificado em seu membro ai_addrlen .

Se o parâmetro pNodeName apontar para um nome de computador, todos os endereços permanentes para o computador que podem ser usados como um endereço de origem serão retornados. No Windows Vista e posterior, esses endereços incluem todos os endereços IP unicast retornados pelas funções GetUnicastIpAddressTable ou GetUnicastIpAddressEntry nas quais o membro SkipAsSource é definido como false na estrutura MIB_UNICASTIPADDRESS_ROW .

Se o parâmetro pNodeName apontar para uma cadeia de caracteres igual a "localhost", todos os endereços de loopback no computador local serão retornados.

Se o parâmetro pNodeName contiver uma cadeia de caracteres vazia, todos os endereços registrados no computador local serão retornados.

No Windows Server 2003 e posterior se o parâmetro pNodeName apontar para uma cadeia de caracteres igual a ".. localmachine", todos os endereços registrados no computador local são retornados.

Se o parâmetro pNodeName se referir a um nome de servidor virtual de cluster, somente endereços de servidor virtual serão retornados. No Windows Vista e posterior, esses endereços incluem todos os endereços IP unicast retornados pelas funções GetUnicastIpAddressTable ou GetUnicastIpAddressEntry nas quais o membro SkipAsSource é definido como true na estrutura MIB_UNICASTIPADDRESS_ROW . Consulte Clustering do Windows para obter mais informações sobre clustering.

O Windows 7 com Service Pack 1 (SP1) e o Windows Server 2008 R2 com Service Pack 1 (SP1) adicionam suporte a Netsh.exe para definir o atributo SkipAsSource em um endereço IP. Isso também altera o comportamento de modo que, se o membro SkipAsSource na estrutura MIB_UNICASTIPADDRESS_ROW estiver definido como false, o endereço IP será registrado no DNS. Se o membro SkipAsSource estiver definido como true, o endereço IP não será registrado no DNS.

Um hotfix está disponível para Windows 7 e Windows Server 2008 R2 que adiciona suporte a Netsh.exe para definir o atributo SkipAsSource em um endereço IP. Esse hotfix também altera o comportamento de modo que, se o membro SkipAsSource na estrutura MIB_UNICASTIPADDRESS_ROW estiver definido como false, o endereço IP será registrado no DNS. Se o membro SkipAsSource estiver definido como true, o endereço IP não será registrado no DNS. Para obter mais informações, consulte Base de Dados de Conhecimento (KB) 2386184.

Um hotfix semelhante também está disponível para Windows Vista com Service Pack 2 (SP2) e Windows Server 2008 com Service Pack 2 (SP2) que adiciona suporte a Netsh.exe para definir o atributo SkipAsSource em um endereço IP. Esse hotfix também altera o comportamento de modo que, se o membro SkipAsSource na estrutura MIB_UNICASTIPADDRESS_ROW estiver definido como false, o endereço IP será registrado no DNS. Se o membro SkipAsSource estiver definido como true, o endereço IP não será registrado no DNS.

Os chamadores da função getaddrinfo podem fornecer dicas sobre o tipo de soquete com suporte por meio de uma estrutura addrinfo apontada pelo parâmetro pHints . Quando o parâmetro pHints é usado, as seguintes regras se aplicam à estrutura addrinfo associada:

  • Um valor de AF_UNSPEC para ai_family indica que o chamador aceitará apenas as famílias de endereços AF_INET e AF_INET6 . Observe que AF_UNSPEC e PF_UNSPEC são iguais.
  • Um valor zero para ai_socktype indica que o chamador aceitará qualquer tipo de soquete.
  • Um valor zero para ai_protocol indica que o chamador aceitará qualquer protocolo.
  • O membro ai_addrlen deve ser definido como zero.
  • O membro ai_canonname deve ser definido como NULL.
  • O membro ai_addr deve ser definido como NULL.
  • O membro ai_next deve ser definido como NULL.

Um valor de AF_UNSPEC para ai_family indica que o chamador aceitará qualquer família de protocolos. Esse valor pode ser usado para retornar endereços IPv4 e IPv6 para o nome do host apontado pelo parâmetro pNodeName . No Windows Server 2003 e no Windows XP, os endereços IPv6 serão retornados somente se o IPv6 estiver instalado no computador local.

Outros valores na estrutura addrinfo fornecida no parâmetro pHints indicam requisitos específicos. Por exemplo, se o chamador manipular apenas IPv4 e não manipular IPv6, o membro ai_family deverá ser definido como AF_INET. Para outro exemplo, se o chamador manipular apenas TCP e não manipular UDP, o membro ai_socktype deverá ser definido como SOCK_STREAM.

Se o parâmetro pHints for um ponteiro NULL , a função getaddrinfo o tratará como se a estrutura addrinfo em pHints fosse inicializada com seu membro ai_family definido como AF_UNSPEC e todos os outros membros definidos como zero.

No Windows Vista e posterior , quando getaddrinfo for chamado de um serviço, se a operação for o resultado de um processo de usuário chamando o serviço, o serviço deverá representar o usuário. Isso é para permitir que a segurança seja aplicada corretamente.

A função getaddrinfo pode ser usada para converter uma representação de cadeia de caracteres de texto de um endereço IP em uma estrutura addrinfo que contém uma estrutura sockaddr para o endereço IP e outras informações. Para ser usada dessa forma, a cadeia de caracteres apontada pelo parâmetro pNodeName deve conter uma representação de texto de um endereço IP e a estrutura addrinfo apontada pelo parâmetro pHints deve ter o sinalizador AI_NUMERICHOST definido no membro ai_flags . A cadeia de caracteres apontada pelo parâmetro pNodeName pode conter uma representação de texto de um endereço IPv4 ou IPv6. O endereço IP de texto é convertido em uma estrutura addrinfo apontada pelo parâmetro ppResult . A estrutura addrinfo retornada contém uma estrutura sockaddr para o endereço IP, juntamente com informações adicionais sobre o endereço IP. Para que esse método funcione com uma cadeia de caracteres de endereço IPv6 no Windows Server 2003 e no Windows XP, o protocolo IPv6 deve ser instalado no computador local. Caso contrário, o erro WSAHOST_NOT_FOUND será retornado.

Liberando informações de endereço da alocação dinâmica

Todas as informações retornadas pela função getaddrinfo apontadas pelo parâmetro ppResult são alocadas dinamicamente, incluindo todas as estruturas addrinfo , estruturas de endereço de soquete e cadeias de caracteres de nome de host canônico apontadas por estruturas addrinfo . A memória alocada por uma chamada bem-sucedida para essa função deve ser liberada com uma chamada subsequente para freeaddrinfo.

Código de exemplo

O exemplo de código a seguir mostra como usar a função 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;
}

Nota Verifique se o ambiente de desenvolvimento tem como destino a versão mais recente do Ws2tcpip.h , que inclui definições de estrutura e função para addrinfo e getaddrinfo, respectivamente.
 

Nomes de domínio internacionalizados

Os nomes de host da Internet normalmente consistem em um conjunto muito restrito de caracteres:
  • Letras maiúsculas e minúsculas ASCII do alfabeto inglês.
  • Dígitos de 0 a 9.
  • Caracteres de hífen ASCII.

Com o crescimento da Internet, há uma necessidade crescente de identificar nomes de host da Internet para outros idiomas não representados pelo conjunto de caracteres ASCII. Identificadores que facilitam essa necessidade e permitem que caracteres não ASCII (Unicode) sejam representados como cadeias de caracteres ASCII especiais são conhecidos como IDNs (Nomes de Domínio Internacionalizados). Um mecanismo chamado IDNA (Internationalizing Domain Names in Applications) é usado para lidar com IDNs de maneira padrão. As especificações para IDNs e IDNA estão documentadas em RFC 3490, RTF 5890 e RFC 6365 publicados pela IETF (Internet Engineering Task Force).

Em Windows 8 e Windows Server 2012, a função getaddrinfo dá suporte à análise de IDN (Nome de Domínio Internacionalizado) aplicada ao nome passado no parâmetro pNodeName. O Winsock executa a codificação e a conversão de Punycode/IDN. Esse comportamento pode ser desabilitado usando o sinalizador AI_DISABLE_IDN_ENCODING discutido abaixo.

No Windows 7 e no Windows Server 2008 R2 ou anterior, a função getaddrinfo atualmente não fornece suporte à análise de IDN aplicada ao nome passado no parâmetro pNodeName . O Winsock não executa nenhuma conversão punycode/IDN. A versão de caractere largo da função GetAddrInfo não usa Punycode para converter um IDN de acordo com RFC 3490. A versão de caractere largo da função GetAddrInfo ao consultar o DNS codifica o nome Unicode no formato UTF-8, o formato usado pelos servidores DNS da Microsoft em um ambiente corporativo.

Várias funções no Windows Vista e posteriores dão suporte à conversão entre rótulos Unicode em um IDN para seus equivalentes ASCII. A representação resultante de cada rótulo Unicode contém apenas caracteres ASCII e começa com o prefixo xn-- se o rótulo Unicode contiver caracteres não ASCII. O motivo para isso é dar suporte a servidores DNS existentes na Internet, já que algumas ferramentas e servidores DNS dão suporte apenas a caracteres ASCII (consulte RFC 3490).

A função IdnToAscii usa Punycode para converter um IDN na representação ASCII da cadeia de caracteres Unicode original usando o algoritmo padrão definido no RFC 3490. A função IdnToUnicode converte a forma ASCII de um IDN para a sintaxe de codificação UTF-16 unicode normal. Para obter mais informações e links para padrões de rascunho relacionados, consulte Manipulando IDNs (nomes de domínio internacionalizados).

A função IdnToAscii pode ser usada para converter um nome IDN no formulário ASCII que, em seguida, pode ser passado no parâmetro pNodeName para a função getaddrinfo . Para passar esse nome IDN para a função GetAddrInfo quando a versão de caractere largo dessa função for usada (quando UNICODE ou _UNICODE for definido), você poderá usar a função MultiByteToWideChar para converter a cadeia de caracteres CHAR em uma cadeia de caracteres WCHAR .

Uso de ai_flags no parâmetro pHints

Sinalizadores no membro ai_flags da estrutura addrinfo opcional fornecida no parâmetro pHints modificam o comportamento da função.

Esses bits de sinalizador são definidos no arquivo de cabeçalho Ws2def.h no Microsoft Software Development Kit do Windows (SDK do Windows) (SDK) para Windows 7. Esses bits de sinalizador são definidos no arquivo de cabeçalho Ws2tcpip.h no SDK do Windows para Windows Server 2008 e Windows Vista. Esses bits de sinalizador são definidos no arquivo de cabeçalho Ws2tcpip.h no SDK da Plataforma para Windows Server 2003 e Windows XP.

Os bits de sinalizador podem ser uma combinação do seguinte:

Bits de sinalizador Descrição
AI_PASSIVE Definir o sinalizador AI_PASSIVE indica que o chamador pretende usar a estrutura de endereço de soquete retornada em uma chamada para a função de associação . Quando o sinalizador AI_PASSIVE é definido e pNodeName é um ponteiro NULL , a parte do endereço IP da estrutura de endereços de soquete é definida como INADDR_ANY para endereços IPv4 e IN6ADDR_ANY_INIT para endereços IPv6.

Quando o sinalizador AI_PASSIVE não estiver definido, a estrutura de endereços de soquete retornada estará pronta para uma chamada para a função de conexão para um protocolo orientado a conexão ou estará pronta para uma chamada para as funções connect, sendto ou send para um protocolo sem conexão. Se o parâmetro pNodeName for um ponteiro NULL nesse caso, a parte do endereço IP da estrutura de endereços do soquete será definida como o endereço de loopback.

AI_CANONNAME Se nem AI_CANONNAME nem AI_NUMERICHOST for usado, a função getaddrinfo tentará a resolução. Se uma cadeia de caracteres literal for passada, getaddrinfo tentará converter a cadeia de caracteres e, se um nome de host for passado, a função getaddrinfo tentará resolve o nome para um endereço ou vários endereços.

Quando o bit AI_CANONNAME é definido, o parâmetro pNodeName não pode ser NULL. Caso contrário, a função getaddrinfo falhará com WSANO_RECOVERY.

Quando o bit AI_CANONNAME é definido e a função getaddrinfo retorna êxito, o membro ai_canonname no parâmetro ppResult aponta para uma cadeia de caracteres terminada em NULL que contém o nome canônico do nó especificado.

Nota A função getaddrinfo pode retornar êxito quando o sinalizador AI_CANONNAME é definido, mas o membro ai_canonname na estrutura addrinfo associada é NULL. Portanto, o uso recomendado do sinalizador AI_CANONNAME inclui testar se o membro ai_canonname na estrutura addrinfo associada é NULL.
 
AI_NUMERICHOST Quando o bit AI_NUMERICHOST é definido, o parâmetro pNodeName deve conter uma cadeia de caracteres de endereço de host numérico não NULL ; caso contrário, o erro EAI_NONAME será retornado. Esse sinalizador impede que um serviço de resolução de nomes seja chamado.
AI_NUMERICSERV Quando o bit AI_NUMERICSERV é definido, o parâmetro pServiceName deve conter um número de porta numérica não NULL , caso contrário, o erro EAI_NONAME é retornado. Esse sinalizador impede que um serviço de resolução de nomes seja chamado.

O sinalizador AI_NUMERICSERV é definido em SDK do Windows para Windows Vista e posteriores. O sinalizador AI_NUMERICSERV não tem suporte dos provedores da Microsoft.

AI_ALL Se o bit AI_ALL estiver definido, uma solicitação será feita para endereços IPv6 e endereços IPv4 com AI_V4MAPPED.

O sinalizador AI_ALL é definido no SDK do Windows para Windows Vista e posteriores. O sinalizador AI_ALL tem suporte no Windows Vista e posterior.

AI_ADDRCONFIG Se o bit AI_ADDRCONFIG estiver definido, getaddrinfo só resolve se um endereço global estiver configurado. Se AI_ADDRCONFIG sinalizador for especificado, os endereços IPv4 serão retornados somente se um endereço IPv4 estiver configurado no sistema local e os endereços IPv6 serão retornados somente se um endereço IPv6 estiver configurado no sistema local. O endereço de loopback IPv4 ou IPv6 não é considerado um endereço global válido.

O sinalizador AI_ADDRCONFIG é definido no SDK do Windows para Windows Vista e posteriores. O sinalizador AI_ADDRCONFIG tem suporte no Windows Vista e posterior.

AI_V4MAPPED Se o bit AI_V4MAPPED estiver definido e uma solicitação para endereços IPv6 falhar, uma solicitação de serviço de nome será feita para endereços IPv4 e esses endereços serão convertidos no formato de endereço IPv6 mapeado por IPv4.

O sinalizador AI_V4MAPPED é definido no SDK do Windows para Windows Vista e posteriores. O sinalizador AI_V4MAPPED tem suporte no Windows Vista e posterior.

AI_NON_AUTHORITATIVE Se o bit AI_NON_AUTHORITATIVE estiver definido, o provedor de namespace NS_EMAIL retornará resultados autoritativos e não autoritativos. Se o bit AI_NON_AUTHORITATIVE não estiver definido, o provedor de namespace NS_EMAIL retornará apenas resultados autoritativos.

O sinalizador AI_NON_AUTHORITATIVE é definido no SDK do Windows para Windows Vista e posteriores. O sinalizador AI_NON_AUTHORITATIVE tem suporte no Windows Vista e posterior e se aplica apenas ao namespace NS_EMAIL .

AI_SECURE Se o bit AI_SECURE estiver definido, o provedor de namespace NS_EMAIL retornará os resultados obtidos com segurança aprimorada para minimizar possíveis falsificações.

O sinalizador AI_SECURE é definido no SDK do Windows para Windows Vista e posteriores. O sinalizador AI_SECURE tem suporte no Windows Vista e posterior e se aplica apenas ao namespace NS_EMAIL .

AI_RETURN_PREFERRED_NAMES Se o AI_RETURN_PREFERRED_NAMES estiver definido, nenhum nome deverá ser fornecido no parâmetro pNodeName . O provedor de namespace NS_EMAIL retornará nomes preferenciais para publicação.

O sinalizador AI_RETURN_PREFERRED_NAMES é definido no SDK do Windows para Windows Vista e posteriores. O sinalizador AI_RETURN_PREFERRED_NAMES tem suporte no Windows Vista e posterior e se aplica apenas ao namespace NS_EMAIL .

AI_FQDN Se o AI_FQDN estiver definido e um nome simples (rótulo único) for especificado, getaddrinfo retornará o nome de domínio totalmente qualificado para o qual o nome acabou sendo resolvido. O nome de domínio totalmente qualificado é retornado no membro ai_canonname na estrutura addrinfo associada. Isso é diferente de AI_CANONNAME sinalizador de bit que retorna o nome canônico registrado no DNS que pode ser diferente do nome de domínio totalmente qualificado para o qual o nome simples foi resolvido. Somente um dos bits AI_FQDN e AI_CANONNAME pode ser definido. A função getaddrinfo falhará se ambos os sinalizadores estiverem presentes com EAI_BADFLAGS.

Quando o bit AI_FQDN é definido, o parâmetro pNodeName não pode ser NULL. Caso contrário, a função GetAddrInfoEx falhará com WSANO_RECOVERY.

Windows 7: O sinalizador AI_FQDN é definido no SDK do Windows para Windows 7 e posterior. O sinalizador AI_FQDN tem suporte no Windows 7 e posterior.

AI_FILESERVER Se o AI_FILESERVER estiver definido, essa será uma dica para o provedor de namespace que o nome do host que está sendo consultado está sendo usado no cenário de compartilhamento de arquivos. O provedor de namespace pode ignorar essa dica.

Windows 7: O sinalizador AI_FILESERVER é definido no SDK do Windows para Windows 7 e posterior. O sinalizador AI_FILESERVER tem suporte no Windows 7 e posterior.

 

Código de exemplo usando AI_NUMERICHOST

O exemplo de código a seguir mostra como usar a função getaddrinfo para converter uma representação de cadeia de caracteres de texto de um endereço IP em uma estrutura addrinfo que contém uma estrutura sockaddr para o endereço IP e outras informações.
#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;
}

Suporte para getaddrinfo no Windows 2000 e versões mais antigas

A função getaddrinfo foi adicionada ao Ws2_32.dll no Windows XP e posterior. Para executar um aplicativo que usa essa função em versões anteriores do Windows, você precisa incluir os arquivos Ws2tcpip.h e Wspiapi.h . Quando o arquivo de inclusão Wspiapi.h é adicionado, a função getaddrinfo é definida para a função embutida WspiapiGetAddrInfo no arquivo Wspiapi.h . No runtime, a função WspiapiGetAddrInfo é implementada de forma que, se o Ws2_32.dll ou o Wship6.dll (o arquivo que contém getaddrinfo na Visualização de Tecnologia IPv6 para Windows 2000) não incluir getaddrinfo, uma versão de getaddrinfo será implementada embutida com base no código no arquivo de cabeçalho Wspiapi.h. Esse código embutido será usado em plataformas windows mais antigas que não dão suporte nativo à função getaddrinfo .

O protocolo IPv6 tem suporte no Windows 2000 quando a Visualização de Tecnologia IPv6 para Windows 2000 está instalada. Caso contrário, o suporte a getaddrinfo em versões do Windows anteriores ao Windows XP é limitado à manipulação da resolução de nomes IPv4.

A função GetAddrInfoW é a versão Unicode de getaddrinfo. A função GetAddrInfoW foi adicionada à Ws2_32.dll no Windows XP com Service Pack 2 (SP2). A função GetAddrInfoW não pode ser usada em versões do Windows anteriores ao Windows XP com SP2.

Windows Phone 8: essa função tem suporte para aplicativos da Windows Phone Store no Windows Phone 8 e posterior.

Windows 8.1 e Windows Server 2012 R2: essa função tem suporte para aplicativos da Windows Store em Windows 8.1, Windows Server 2012 R2 e posteriores.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP]
Servidor mínimo com suporte Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP]
Plataforma de Destino Windows
Cabeçalho ws2tcpip.h
Biblioteca Ws2_32.lib
DLL Ws2_32.dll

Confira também

GetAddrInfoEx

GetAddrInfoW

IdnToAscii

IdnToUnicode

Wsagetlasterror

Wsasocket

Funções Winsock

Referência de Winsock

Addrinfo

addrinfoW

addrinfoex

addrinfoex2

bind

connect

freeaddrinfo

gai_strerror

send

Sendto

socket