Compartir a través de


Función getaddrinfo (ws2tcpip.h)

La función getaddrinfo proporciona una traducción independiente del protocolo de un nombre de host ANSI a una dirección.

Sintaxis

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

Parámetros

[in, optional] pNodeName

Puntero a una cadena ANSI terminada en NULL que contiene un nombre de host (nodo) o una cadena de dirección de host numérica. Para el protocolo de Internet, la cadena de dirección de host numérica es una dirección IPv4 decimal con puntos o una dirección hexadecimal IPv6.

[in, optional] pServiceName

Puntero a una cadena ANSI terminada en NULL que contiene un nombre de servicio o un número de puerto representado como una cadena.

Un nombre de servicio es un alias de cadena para un número de puerto. Por ejemplo, "http" es un alias para el puerto 80 definido por el Grupo de tareas de ingeniería de Internet (IETF) como el puerto predeterminado que usan los servidores web para el protocolo HTTP. Los valores posibles para el parámetro pServiceName cuando no se especifica un número de puerto se muestran en el siguiente archivo:

%WINDIR%\system32\drivers\etc\services

[in, optional] pHints

Puntero a una estructura addrinfo que proporciona sugerencias sobre el tipo de socket que admite el llamador.

Los miembros ai_addrlen, ai_canonname, ai_addr y ai_next de la estructura addrinfo a la que apunta el parámetro pHints deben ser cero o NULL. De lo contrario, se producirá un error en la función GetAddrInfoEx con WSANO_RECOVERY.

Consulte los comentarios para obtener más detalles.

[out] ppResult

Puntero a una lista vinculada de una o varias estructuras addrinfo que contiene información de respuesta sobre el host.

Valor devuelto

Success devuelve cero. Error devuelve un código de error de Windows Sockets distinto de cero, como se encuentra en los códigos de error de Windows Sockets.

La mayoría de los códigos de error distintos de cero devueltos por la función getaddrinfo se asignan al conjunto de errores descritos por las recomendaciones del Grupo de tareas de ingeniería de Internet (IETF). En la tabla siguiente se enumeran estos códigos de error y sus equivalentes de WSA. Se recomienda usar los códigos de error de WSA, ya que ofrecen información de error familiar y completa para los programadores de Winsock.

Valor de error WSA equivalente Descripción
EAI_AGAIN WSATRY_AGAIN Error temporal en la resolución de nombres.
EAI_BADFLAGS WSAEINVAL Se proporcionó un valor no válido para el miembro ai_flags del parámetro pHints .
EAI_FAIL WSANO_RECOVERY Error irrecuperable en la resolución de nombres.
EAI_FAMILY WSAEAFNOSUPPORT No se admite el miembro ai_family del parámetro pHints .
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY Error de asignación de memoria.
EAI_NONAME WSAHOST_NOT_FOUND El nombre no se resuelve para los parámetros proporcionados o no se proporcionaron los parámetros pNodeName y pServiceName .
EAI_SERVICE WSATYPE_NOT_FOUND El parámetro pServiceName no se admite para el miembro ai_socktype especificado del parámetro pHints .
EAI_SOCKTYPE WSAESOCKTNOSUPPORT No se admite el miembro ai_socktype del parámetro pHints .
 

Use la función gai_strerror para imprimir mensajes de error basados en los códigos EAI devueltos por la función getaddrinfo . La función gai_strerror se proporciona para cumplir las recomendaciones de IETF, pero no es segura para subprocesos. Por lo tanto, se recomienda el uso de funciones tradicionales de Windows Sockets, como WSAGetLastError .

Código de error Significado
WSA_NOT_ENOUGH_MEMORY
No había memoria suficiente para realizar la operación.
WSAEAFNOSUPPORT
Se ha usado una dirección incompatible con el protocolo solicitado. Este error se devuelve si no se admite el ai_family miembro de la estructura addrinfo a la que apunta el parámetro pHints .
WSAEINVAL
Se ha proporcionado un argumento no válido. Este error se devuelve si se proporcionó un valor no válido para el miembro ai_flags de la estructura addrinfo a la que apunta el parámetro pHints .
WSAESOCKTNOSUPPORT
Esta familia de direcciones no es compatible con el tipo de socket especificado. Este error se devuelve si no se admite el miembro ai_socktype de la estructura addrinfo a la que apunta el parámetro pHints .
WSAHOST_NOT_FOUND
Se desconoce el host. Este error se devuelve si el nombre no se resuelve para los parámetros proporcionados o no se proporcionaron los parámetros pNodeName y pServiceName .
WSANO_DATA
El nombre solicitado es válido, pero no se ha encontrado ningún dato del tipo solicitado.
WSANO_RECOVERY
Se produjo un error no recuperable durante una búsqueda de base de datos. Este error se devuelve si se produjo un error irrecuperable en la resolución de nombres.
WSANOTINITIALISED
Debe producirse una llamada WSAStartup correcta antes de usar esta función.
WSATRY_AGAIN
Éste es normalmente un error temporal durante la resolución de nombres de host y significa que el servidor local no recibió una respuesta de un servidor autorizado. Este error se devuelve cuando se produjo un error temporal en la resolución de nombres.
WSATYPE_NOT_FOUND
No se encontró la clase especificada. El parámetro pServiceName no se admite para el miembro de ai_socktype especificado de la estructura addrinfo a la que apunta el parámetro pHints .

Comentarios

La función getaddrinfo es la versión ANSI de una función que proporciona traducción independiente del protocolo del nombre de host a la dirección. La versión Unicode de esta función es GetAddrInfoW. Se recomienda a los desarrolladores que usen la función Unicode GetAddrInfoW en lugar de la función ANSI getaddrinfo .

La función getaddrinfo devuelve resultados para el espacio de nombres NS_DNS. La función getaddrinfo agrega todas las respuestas si más de un proveedor de espacios de nombres devuelve información. Para su uso con el protocolo IPv6 e IPv4, la resolución de nombres puede ser por el Sistema de nombres de dominio (DNS), un archivo de hosts local o por otros mecanismos de nomenclatura para el espacio de nombres NS_DNS .

Otro nombre que se puede usar para la función getaddrinfo es GetAddrInfoA. Las macros del archivo de encabezado Ws2tcpip.h definen GetAddrInfoA para getaddrinfo.

Las macros del archivo de encabezado Ws2tcpip.h definen un nombre de función de mayúsculas y minúsculas mixtas de GetAddrInfo y una estructura ADDRINFOT . Se debe llamar a esta función GetAddrInfo con los parámetros pNodeName y pServiceName de un puntero de tipo TCHAR y los parámetros pHints y ppResult de un puntero de tipo ADDRINFOT. Cuando no se define UNICODE o _UNICODE, GetAddrInfo se define en getaddrinfo, la versión ANSI de la función y ADDRINFOT se define en la estructura addrinfo . Cuando se define UNICODE o _UNICODE , GetAddrInfo se define en GetAddrInfoW, la versión Unicode de la función y ADDRINFOT se define en la estructura addrinfoW .

Los nombres de parámetro y los tipos de parámetro para la función getaddrinfo definida en el archivo de encabezado Ws2tcpip.h en el Kit de desarrollo de software de plataforma (SDK) para Windows Server 2003 y Windows XP eran diferentes.

Uno o ambos parámetros pNodeName o pServiceName deben apuntar a una cadena ANSI terminada en NULL; por lo general, ambos se proporcionan.

Tras la operación correcta, se devuelve una lista vinculada de estructuras addrinfo en el parámetro ppResult . La lista se puede procesar siguiendo el puntero proporcionado en el miembro ai_next de cada estructura addrinfo devuelta hasta que se encuentre un puntero NULL . En cada estructura addrinfo devuelta, los miembros ai_family, ai_socktype y ai_protocol corresponden a los argumentos respectivos en una llamada de función de socket o WSASocket. Además, el miembro ai_addr de cada estructura addrinfo devuelta apunta a una estructura de direcciones de socket rellenada, la longitud de la cual se especifica en su miembro ai_addrlen .

Si el parámetro pNodeName apunta a un nombre de equipo, se devuelven todas las direcciones permanentes del equipo que se pueden usar como dirección de origen. En Windows Vista y versiones posteriores, estas direcciones incluirían todas las direcciones IP de unidifusión devueltas por las funciones GetUnicastIpAddressTable o GetUnicastIpAddressEntry en las que el miembro SkipAsSource se establece en false en la estructura MIB_UNICASTIPADDRESS_ROW .

Si el parámetro pNodeName apunta a una cadena igual a "localhost", se devuelven todas las direcciones de bucle invertido del equipo local.

Si el parámetro pNodeName contiene una cadena vacía, se devuelven todas las direcciones registradas en el equipo local.

En Windows Server 2003 y versiones posteriores, si el parámetro pNodeName apunta a una cadena igual a ".. localmachine", se devuelven todas las direcciones registradas en el equipo local.

Si el parámetro pNodeName hace referencia a un nombre de servidor virtual de clúster, solo se devuelven las direcciones del servidor virtual. En Windows Vista y versiones posteriores, estas direcciones incluirían todas las direcciones IP de unidifusión devueltas por las funciones GetUnicastIpAddressTable o GetUnicastIpAddressEntry en las que el miembro SkipAsSource se establece en true en la estructura MIB_UNICASTIPADDRESS_ROW . Consulte Clústeres de Windows para obtener más información sobre la agrupación en clústeres.

Windows 7 con Service Pack 1 (SP1) y Windows Server 2008 R2 con Service Pack 1 (SP1) agregan compatibilidad con Netsh.exe para establecer el atributo SkipAsSource en una dirección IP. Esto también cambia el comportamiento de modo que si el miembro SkipAsSource de la estructura MIB_UNICASTIPADDRESS_ROW está establecido en false, la dirección IP se registrará en DNS. Si el miembro SkipAsSource se establece en true, la dirección IP no se registra en DNS.

Hay disponible una revisión para Windows 7 y Windows Server 2008 R2 que agrega compatibilidad a Netsh.exe para establecer el atributo SkipAsSource en una dirección IP. Esta revisión también cambia el comportamiento de forma que si el miembro SkipAsSource de la estructura MIB_UNICASTIPADDRESS_ROW está establecido en false, la dirección IP se registrará en DNS. Si el miembro SkipAsSource se establece en true, la dirección IP no se registra en DNS. Para obtener más información, vea Knowledge Base (KB) 2386184.

También hay disponible una revisión similar para Windows Vista con Service Pack 2 (SP2) y Windows Server 2008 con Service Pack 2 (SP2) que agrega compatibilidad a Netsh.exe para establecer el atributo SkipAsSource en una dirección IP. Esta revisión también cambia el comportamiento de forma que si el miembro SkipAsSource de la estructura MIB_UNICASTIPADDRESS_ROW está establecido en false, la dirección IP se registrará en DNS. Si el miembro SkipAsSource se establece en true, la dirección IP no se registra en DNS.

Los autores de llamadas de la función getaddrinfo pueden proporcionar sugerencias sobre el tipo de socket admitido a través de una estructura addrinfo a la que apunta el parámetro pHints . Cuando se usa el parámetro pHints , se aplican las siguientes reglas a su estructura addrinfo asociada:

  • Un valor de AF_UNSPEC para ai_family indica que el autor de la llamada aceptará solo las familias de direcciones AF_INET y AF_INET6 . Tenga en cuenta que AF_UNSPEC y PF_UNSPEC son los mismos.
  • Un valor de cero para ai_socktype indica que el autor de la llamada aceptará cualquier tipo de socket.
  • Un valor de cero para ai_protocol indica que el autor de la llamada aceptará cualquier protocolo.
  • El miembro ai_addrlen debe establecerse en cero.
  • El miembro ai_canonname debe establecerse en NULL.
  • El miembro ai_addr debe establecerse en NULL.
  • El miembro ai_next debe establecerse en NULL.

Un valor de AF_UNSPEC para ai_family indica que el autor de la llamada aceptará cualquier familia de protocolos. Este valor se puede usar para devolver direcciones IPv4 e IPv6 para el nombre de host al que apunta el parámetro pNodeName . En Windows Server 2003 y Windows XP, las direcciones IPv6 solo se devuelven si IPv6 está instalado en el equipo local.

Otros valores de la estructura addrinfo proporcionada en el parámetro pHints indican requisitos específicos. Por ejemplo, si el autor de la llamada solo controla IPv4 y no controla IPv6, el miembro ai_family debe establecerse en AF_INET. Por otro ejemplo, si el autor de la llamada solo controla TCP y no controla UDP, el miembro ai_socktype debe establecerse en SOCK_STREAM.

Si el parámetro pHints es un puntero NULL , la función getaddrinfo la trata como si la estructura addrinfo de pHints se inicializara con su miembro ai_family establecido en AF_UNSPEC y todos los demás miembros establecidos en cero.

En Windows Vista y versiones posteriores cuando se llama a getaddrinfo desde un servicio, si la operación es el resultado de un proceso de usuario que llama al servicio, el servicio debe suplantar al usuario. Esto es para permitir que la seguridad se aplique correctamente.

La función getaddrinfo se puede usar para convertir una representación de cadena de texto de una dirección IP en una estructura addrinfo que contiene una estructura sockaddr para la dirección IP y otra información. Para usarse de esta manera, la cadena a la que apunta el parámetro pNodeName debe contener una representación de texto de una dirección IP y la estructura addrinfo a la que apunta el parámetro pHints debe tener la marca AI_NUMERICHOST establecida en el miembro ai_flags . La cadena a la que apunta el parámetro pNodeName puede contener una representación de texto de una dirección IPv4 o IPv6. La dirección IP de texto se convierte en una estructura addrinfo a la que apunta el parámetro ppResult . La estructura addrinfo devuelta contiene una estructura sockaddr para la dirección IP junto con información adicional sobre la dirección IP. Para que este método funcione con una cadena de dirección IPv6 en Windows Server 2003 y Windows XP, el protocolo IPv6 debe instalarse en el equipo local. De lo contrario, se devuelve el error WSAHOST_NOT_FOUND .

Liberar información de direcciones de la asignación dinámica

Toda la información devuelta por la función getaddrinfo a la que apunta el parámetro ppResult se asigna dinámicamente, incluidas todas las estructuras addrinfo , las estructuras de dirección de socket y las cadenas de nombre de host canónicas a las que apuntan las estructuras addrinfo . La memoria asignada por una llamada correcta a esta función debe liberarse con una llamada posterior a freeaddrinfo.

Código de ejemplo

En el ejemplo de código siguiente se muestra cómo usar la función 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 Asegúrese de que el entorno de desarrollo tiene como destino la versión más reciente de Ws2tcpip.h , que incluye definiciones de estructura y función para addrinfo y getaddrinfo, respectivamente.
 

Nombres de dominio internacionalizados

Los nombres de host de Internet normalmente constan de un conjunto de caracteres muy restringido:
  • Letras ASCII mayúsculas y minúsculas del alfabeto inglés.
  • Dígitos del 0 al 9.
  • Caracteres de guion ASCII.

Con el crecimiento de Internet, hay una creciente necesidad de identificar los nombres de host de Internet para otros idiomas no representados por el juego de caracteres ASCII. Los identificadores que facilitan esta necesidad y permiten representar caracteres no ASCII (Unicode) como cadenas de caracteres ASCII especiales se conocen como nombres de dominio internacionalizados (IDN). Un mecanismo denominado Internationalizing Domain Names in Applications (IDNA) se usa para controlar los IDN de forma estándar. Las especificaciones de IDN e IDNA se documentan en RFC 3490, RTF 5890 y RFC 6365 publicados por el Grupo de tareas de ingeniería de Internet (IETF).

En Windows 8 y Windows Server 2012, la función getaddrinfo proporciona compatibilidad con el análisis de nombres de dominio internacionalizados (IDN) aplicados al nombre pasado en el parámetro pNodeName . Winsock realiza la codificación y conversión de Punycode/IDN. Este comportamiento se puede deshabilitar con la marca AI_DISABLE_IDN_ENCODING que se describe a continuación.

En Windows 7 y Windows Server 2008 R2 o versiones anteriores, la función getaddrinfo no proporciona actualmente el análisis de IDN de compatibilidad aplicado al nombre pasado en el parámetro pNodeName . Winsock no realiza ninguna conversión punycode/IDN. La versión de caracteres anchos de la función GetAddrInfo no usa Punycode para convertir un IDN según RFC 3490. La versión de caracteres anchos de la función GetAddrInfo al consultar DNS codifica el nombre Unicode en formato UTF-8, el formato que usan los servidores DNS de Microsoft en un entorno empresarial.

Varias funciones en Windows Vista y versiones posteriores admiten la conversión entre etiquetas Unicode en un IDN a sus equivalentes ASCII. La representación resultante de cada etiqueta Unicode contiene solo caracteres ASCII y comienza con el prefijo xn-- si la etiqueta Unicode contenía caracteres no ASCII. El motivo es admitir servidores DNS existentes en Internet, ya que algunas herramientas y servidores DNS solo admiten caracteres ASCII (consulte RFC 3490).

La función IdnToAscii usa Punycode para convertir un IDN en la representación ASCII de la cadena Unicode original mediante el algoritmo estándar definido en RFC 3490. La función IdnToUnicode convierte la forma ASCII de un IDN en la sintaxis normal de codificación UTF-16 de Unicode. Para obtener más información y vínculos a estándares de borrador relacionados, consulte Control de nombres de dominio internacionalizados (IDN).

La función IdnToAscii se puede usar para convertir un nombre IDN en el formulario ASCII que, a continuación, se puede pasar en el parámetro pNodeName a la función getaddrinfo . Para pasar este nombre IDN a la función GetAddrInfo cuando se usa la versión de caracteres anchos de esta función (cuando se define UNICODE o _UNICODE), puede usar la función MultiByteToWideChar para convertir la cadena CHAR en una cadena WCHAR .

Uso de ai_flags en el parámetro pHints

Las marcas del miembro ai_flags de la estructura addrinfo opcional proporcionada en el parámetro pHints modifican el comportamiento de la función.

Estos bits de marca se definen en el archivo de encabezado Ws2def.h en el Kit de desarrollo de software (SDK) de Microsoft Windows para Windows 7. Estos bits de marca se definen en el archivo de encabezado Ws2tcpip.h en windows SDK para Windows Server 2008 y Windows Vista. Estos bits de marca se definen en el archivo de encabezado Ws2tcpip.h en el SDK de plataforma para Windows Server 2003 y Windows XP.

Los bits de marca pueden ser una combinación de lo siguiente:

Bits de marca Descripción
AI_PASSIVE Establecer la marca AI_PASSIVE indica que el autor de la llamada pretende usar la estructura de direcciones de socket devuelta en una llamada a la función bind . Cuando se establece la marca de AI_PASSIVE y pNodeName es un puntero NULL , la parte de la dirección IP de la estructura de direcciones de socket se establece en INADDR_ANY para las direcciones IPv4 y IN6ADDR_ANY_INIT para las direcciones IPv6.

Cuando no se establece la marca de AI_PASSIVE , la estructura de direcciones de socket devuelta está lista para una llamada a la función connect para un protocolo orientado a la conexión o lista para una llamada a las funciones connect, sendto o send para un protocolo sin conexión. Si el parámetro pNodeName es un puntero NULL en este caso, la parte de la dirección IP de la estructura de direcciones de socket se establece en la dirección de bucle invertido.

AI_CANONNAME Si no se usa ni AI_CANONNAME ni AI_NUMERICHOST , la función getaddrinfo intenta la resolución. Si se pasa una cadena literal getaddrinfo intenta convertir la cadena y, si se pasa un nombre de host, la función getaddrinfo intenta resolver el nombre en una dirección o en varias direcciones.

Cuando se establece el bit de AI_CANONNAME , el parámetro pNodeName no puede ser NULL. De lo contrario, se producirá un error en la función getaddrinfo con WSANO_RECOVERY.

Cuando se establece el bit de AI_CANONNAME y la función getaddrinfo devuelve correctamente, el miembro ai_canonname del parámetro ppResult apunta a una cadena terminada en NULL que contiene el nombre canónico del nodo especificado.

Nota La función getaddrinfo puede devolver el éxito cuando se establece la marca de AI_CANONNAME , pero el miembro ai_canonname de la estructura addrinfo asociada es NULL. Por lo tanto, el uso recomendado de la marca AI_CANONNAME incluye probar si el miembro ai_canonname de la estructura addrinfo asociada es NULL.
 
AI_NUMERICHOST Cuando se establece el bit de AI_NUMERICHOST , el parámetro pNodeName debe contener una cadena de dirección de host numérica que no sea NULL ; de lo contrario, se devuelve el error EAI_NONAME . Esta marca impide que se llame a un servicio de resolución de nombres.
AI_NUMERICSERV Cuando se establece el bit de AI_NUMERICSERV , el parámetro pServiceName debe contener un número de puerto numérico distinto de NULL ; de lo contrario, se devuelve el error EAI_NONAME . Esta marca impide que se llame a un servicio de resolución de nombres.

La marca AI_NUMERICSERV se define en Windows SDK para Windows Vista y versiones posteriores. Los proveedores de Microsoft no admiten la marca AI_NUMERICSERV .

AI_ALL Si se establece el bit de AI_ALL , se realiza una solicitud para las direcciones IPv6 e IPv4 con AI_V4MAPPED.

La marca AI_ALL se define en Windows SDK para Windows Vista y versiones posteriores. La marca AI_ALL se admite en Windows Vista y versiones posteriores.

AI_ADDRCONFIG Si se establece el bit de AI_ADDRCONFIG , getaddrinfo solo se resolverá si se configura una dirección global. Si se especifica AI_ADDRCONFIG marca, las direcciones IPv4 solo se devolverán si se configura una dirección IPv4 en el sistema local y las direcciones IPv6 solo se devolverán si se configura una dirección IPv6 en el sistema local. La dirección de bucle invertido IPv4 o IPv6 no se considera una dirección global válida.

La marca AI_ADDRCONFIG se define en Windows SDK para Windows Vista y versiones posteriores. La marca AI_ADDRCONFIG se admite en Windows Vista y versiones posteriores.

AI_V4MAPPED Si se establece el bit de AI_V4MAPPED y se produce un error en una solicitud de direcciones IPv6, se realiza una solicitud de servicio de nombre para las direcciones IPv4 y estas direcciones se convierten en formato de dirección IPv6 asignado a IPv4.

La marca AI_V4MAPPED se define en Windows SDK para Windows Vista y versiones posteriores. La marca AI_V4MAPPED se admite en Windows Vista y versiones posteriores.

AI_NON_AUTHORITATIVE Si se establece el bit de AI_NON_AUTHORITATIVE , el proveedor de espacio de nombres NS_EMAIL devuelve resultados autoritativos y no autoritativos. Si no se establece el bit de AI_NON_AUTHORITATIVE , el proveedor de espacio de nombres NS_EMAIL devuelve solo los resultados autoritativos.

La marca AI_NON_AUTHORITATIVE se define en Windows SDK para Windows Vista y versiones posteriores. La marca AI_NON_AUTHORITATIVE se admite en Windows Vista y versiones posteriores y solo se aplica al espacio de nombres NS_EMAIL .

AI_SECURE Si se establece el bit de AI_SECURE , el proveedor de espacio de nombres NS_EMAIL devolverá los resultados obtenidos con seguridad mejorada para minimizar la posible suplantación de identidad.

La marca AI_SECURE se define en Windows SDK para Windows Vista y versiones posteriores. La marca AI_SECURE se admite en Windows Vista y versiones posteriores y solo se aplica al espacio de nombres NS_EMAIL .

AI_RETURN_PREFERRED_NAMES Si se establece el AI_RETURN_PREFERRED_NAMES , no se debe proporcionar ningún nombre en el parámetro pNodeName . El proveedor de espacio de nombres NS_EMAIL devolverá nombres preferidos para la publicación.

La marca AI_RETURN_PREFERRED_NAMES se define en Windows SDK para Windows Vista y versiones posteriores. La marca AI_RETURN_PREFERRED_NAMES se admite en Windows Vista y versiones posteriores y solo se aplica al espacio de nombres NS_EMAIL .

AI_FQDN Si se establece el AI_FQDN y se especifica un nombre plano (etiqueta única), getaddrinfo devolverá el nombre de dominio completo al que finalmente se resolvió el nombre. El nombre de dominio completo se devuelve en el miembro ai_canonname de la estructura addrinfo asociada. Esto es diferente de AI_CANONNAME marca de bits que devuelve el nombre canónico registrado en DNS, que puede ser diferente del nombre de dominio completo al que se resolvió el nombre plano. Solo se puede establecer uno de los bits de AI_FQDN y AI_CANONNAME . Se producirá un error en la función getaddrinfo si ambas marcas están presentes con EAI_BADFLAGS.

Cuando se establece el bit de AI_FQDN , el parámetro pNodeName no puede ser NULL. De lo contrario, se producirá un error en la función GetAddrInfoEx con WSANO_RECOVERY.

Windows 7: La marca AI_FQDN se define en Windows SDK para Windows 7 y versiones posteriores. La marca AI_FQDN se admite en Windows 7 y versiones posteriores.

AI_FILESERVER Si se establece el AI_FILESERVER , se trata de una sugerencia para el proveedor de espacios de nombres que se está consultando el nombre de host que se está consultando en el escenario del recurso compartido de archivos. El proveedor de espacios de nombres puede omitir esta sugerencia.

Windows 7: La marca AI_FILESERVER se define en Windows SDK para Windows 7 y versiones posteriores. La marca AI_FILESERVER se admite en Windows 7 y versiones posteriores.

 

Código de ejemplo mediante AI_NUMERICHOST

En el ejemplo de código siguiente se muestra cómo usar la función getaddrinfo para convertir una representación de cadena de texto de una dirección IP en una estructura addrinfo que contiene una estructura sockaddr para la dirección IP y otra información.
#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;
}

Compatibilidad con getaddrinfo en Windows 2000 y versiones anteriores

La función getaddrinfo se agregó al Ws2_32.dll en Windows XP y versiones posteriores. Para ejecutar una aplicación que use esta función en versiones anteriores de Windows, debe incluir los archivos Ws2tcpip.h y Wspiapi.h . Cuando se agrega el archivo de inclusión Wspiapi.h , la función getaddrinfo se define en la función insertada WspiapiGetAddrInfo en el archivo Wspiapi.h . En tiempo de ejecución, la función WspiapiGetAddrInfo se implementa de forma que si el Ws2_32.dll o el Wship6.dll (el archivo que contiene getaddrinfo en la versión preliminar de tecnología IPv6 para Windows 2000) no incluye getaddrinfo, entonces una versión de getaddrinfo se implementa insertada en función del código en el archivo de encabezado Wspiapi.h. Este código insertado se usará en plataformas de Windows anteriores que no admiten de forma nativa la función getaddrinfo .

El protocolo IPv6 es compatible con Windows 2000 cuando se instala la versión preliminar de tecnología IPv6 para Windows 2000. De lo contrario, la compatibilidad con getaddrinfo en versiones de Windows anteriores a Windows XP se limita a controlar la resolución de nombres IPv4.

La función GetAddrInfoW es la versión Unicode de getaddrinfo. La función GetAddrInfoW se agregó a la Ws2_32.dll en Windows XP con Service Pack 2 (SP2). La función GetAddrInfoW no se puede usar en versiones de Windows anteriores a Windows XP con SP2.

Windows Phone 8: Esta función es compatible con las aplicaciones de la Tienda de Windows Phone en Windows Phone 8 y versiones posteriores.

Windows 8.1 y Windows Server 2012 R2: esta función es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.

Requisitos

Requisito Value
Cliente mínimo compatible Windows XP, Windows 8.1 [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado ws2tcpip.h
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

GetAddrInfoEx

GetAddrInfoW

IdnToAscii

IdnToUnicode

WSAGetLastError

WSASocket

Funciones winsock

Referencia de Winsock

addrinfo

addrinfoW

addrinfoex

addrinfoex2

bind

connect

freeaddrinfo

gai_strerror

enviar

sendto

socket