Estructura ADDRINFOW (ws2def.h)

La estructura addrinfoW la usa la función GetAddrInfoW para contener la información de dirección del host.

Sintaxis

typedef struct addrinfoW {
  int              ai_flags;
  int              ai_family;
  int              ai_socktype;
  int              ai_protocol;
  size_t           ai_addrlen;
  PWSTR            ai_canonname;
  struct sockaddr  *ai_addr;
  struct addrinfoW *ai_next;
} ADDRINFOW, *PADDRINFOW;

Miembros

ai_flags

Tipo: int

Marcas que indican las opciones usadas en la función GetAddrInfoW .

Los valores admitidos para el miembro ai_flags se definen en el archivo de encabezado Winsock2.h y pueden ser una combinación de las opciones enumeradas en la tabla siguiente.

Valor Significado
AI_PASSIVE
0x01
La dirección del socket se usará en una llamada a la función bind .
AI_CANONNAME
0x02
El nombre canónico se devuelve en el primer miembro ai_canonname .
AI_NUMERICHOST
0x04
El parámetro nodename pasado a la función GetAddrInfoW debe ser una cadena numérica.
AI_ALL
0x0100
Si se establece este bit, se realiza una solicitud para las direcciones IPv6 e IPv4 con AI_V4MAPPED.

Esta opción se admite en Windows Vista y versiones posteriores.

AI_ADDRCONFIG
0x0400
GetAddrInfoW solo se resolverá si se configura una dirección global. La dirección de bucle invertido IPv6 e IPv4 no se considera una dirección global válida. Esta opción solo se admite en Windows Vista y versiones posteriores.
AI_V4MAPPED
0x0800
Si se produce un error en la solicitud GetAddrInfoW de una dirección 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.

Esta opción se admite en Windows Vista y versiones posteriores.

AI_NON_AUTHORITATIVE
0x04000
La información de dirección puede ser de un proveedor de espacios de nombres no autoritativo.

Esta opción solo se admite en Windows Vista y versiones posteriores para el espacio de nombres NS_EMAIL .

AI_SECURE
0x08000
La información de dirección procede de un canal seguro.

Esta opción solo se admite en Windows Vista y versiones posteriores para el espacio de nombres NS_EMAIL .

AI_RETURN_PREFERRED_NAMES
0x010000
La información de dirección es para un nombre preferido para un usuario.

Esta opción solo se admite en Windows Vista y versiones posteriores para el espacio de nombres NS_EMAIL .

AI_FQDN
0x00020000
Si se especifica un nombre plano (etiqueta única), GetAddrInfoW devolverá el nombre de dominio completo al que se resolvió el nombre. El nombre de dominio completo se devuelve en el miembro ai_canonname .

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 GetAddrInfoW si ambas marcas están presentes con EAI_BADFLAGS.

Esta opción se admite en Windows 7, Windows Server 2008 R2 y versiones posteriores.

AI_FILESERVER
0x00040000
Sugerencia al proveedor de espacios de nombres que se está consultando el nombre de host se está usando en un escenario de recurso compartido de archivos. El proveedor de espacios de nombres puede omitir esta sugerencia.

Esta opción se admite en Windows 7, Windows Server 2008 R2 y versiones posteriores.

AI_DISABLE_IDN_ENCODING
0x00080000
Deshabilite la codificación automática de nombres de dominio internacionales mediante Punycode en las funciones de resolución de nombres llamadas por la función GetAddrInfoW .

Esta opción se admite en Windows 8, Windows Server 2012 y versiones posteriores.

ai_family

Tipo: int

La familia de direcciones. Los valores posibles para la familia de direcciones se definen en el archivo de encabezado Winsock2.h .

En el Windows SDK publicado para Windows Vista y versiones posteriores, la organización de los archivos de encabezado ha cambiado y los valores posibles para la familia de direcciones se definen en el archivo de encabezado Ws2def.h. Tenga en cuenta que el archivo de encabezado Ws2def.h se incluye automáticamente en Winsock2.h y nunca se debe usar directamente.

Los valores admitidos actualmente son AF_INET o AF_INET6, que son los formatos de familia de direcciones de Internet para IPv4 e IPv6. Se admiten otras opciones para la familia de direcciones (AF_NETBIOS para su uso con NetBIOS, por ejemplo) si se instala un proveedor de servicios de Windows Sockets para la familia de direcciones. Tenga en cuenta que los valores de la familia de direcciones AF_ y las constantes de familia de protocolos PF_ son idénticas (por ejemplo, AF_UNSPEC y PF_UNSPEC), por lo que se puede usar cualquiera de las constantes.

En la tabla siguiente se enumeran los valores comunes de la familia de direcciones, aunque muchos otros valores son posibles.

Valor Significado
AF_UNSPEC
0
No se especifica la familia de direcciones.
AF_INET
2
Familia de direcciones del Protocolo de Internet versión 4 (IPv4).
AF_NETBIOS
17
Familia de direcciones NetBIOS. Esta familia de direcciones solo se admite si está instalado un proveedor de Windows Sockets para NetBIOS.
AF_INET6
23
Familia de direcciones del Protocolo de Internet versión 6 (IPv6).
AF_IRDA
26
Familia de direcciones de la Asociación de datos infrarrojos (IrDA). Esta familia de direcciones solo se admite si el equipo tiene instalado un puerto infrarrojo y un controlador.
AF_BTH
32
La familia de direcciones Bluetooth. Esta familia de direcciones solo se admite si se instala un adaptador Bluetooth en Windows Server 2003 o posterior.

ai_socktype

Tipo: int

Tipo de socket. Los valores posibles para el tipo de socket se definen en el archivo de inclusión Winsock2.h .

En la tabla siguiente se enumeran los valores posibles para el tipo de socket admitido para Windows Sockets 2.

Valor Significado
SOCK_STREAM
1
Proporciona secuencias de bytes secuenciadas, confiables, bidireccionales y basadas en conexiones con un mecanismo de transmisión de datos OOB. Usa el Protocolo de control de transmisión (TCP) para la familia de direcciones de Internet (AF_INET o AF_INET6). Si el miembro ai_family es AF_IRDA, SOCK_STREAM es el único tipo de socket admitido.
SOCK_DGRAM
2
Admite datagramas, que son búferes no confiables sin conexión con una longitud máxima fija (normalmente corta). Usa el Protocolo de datagramas de usuario (UDP) para la familia de direcciones de Internet (AF_INET o AF_INET6).
SOCK_RAW
3
Proporciona un socket sin formato que permite a una aplicación manipular el siguiente encabezado de protocolo de capa superior. Para manipular el encabezado IPv4, la opción de socket IP_HDRINCL debe establecerse en el socket. Para manipular el encabezado IPv6, la opción de socket IPV6_HDRINCL debe establecerse en el socket.
SOCK_RDM
4
Proporciona un datagrama de mensaje confiable. Un ejemplo de este tipo es la implementación del protocolo de multidifusión general pragmática (PGM) en Windows, a menudo denominada programación de multidifusión confiable.
SOCK_SEQPACKET
5
Proporciona un paquete pseudo-stream basado en datagramas.
 

En Windows Sockets 2, se introdujeron nuevos tipos de socket. Una aplicación puede detectar dinámicamente los atributos de cada protocolo de transporte disponible a través de la función WSAEnumProtocols . Por lo tanto, una aplicación puede determinar las posibles opciones de tipo de socket y protocolo para una familia de direcciones y usar esta información al especificar este parámetro. Las definiciones de tipo de socket en los archivos de encabezado Winsock2.h y Ws2def.h se actualizarán periódicamente a medida que se definen nuevos tipos de socket, familias de direcciones y protocolos.

En Windows Sockets 1.1, los únicos tipos de socket posibles son SOCK_DATAGRAM y SOCK_STREAM.

ai_protocol

Tipo: int

Tipo de protocolo. Las opciones posibles son específicas de la familia de direcciones y el tipo de socket especificado. Los valores posibles para el ai_protocol se definen en Winsock2.h y en los archivos de encabezado Wsrm.h .

En el Windows SDK publicado para Windows Vista y versiones posteriores, la organización de los archivos de encabezado ha cambiado y este miembro puede ser uno de los valores del tipo de enumeración IPPROTO definido en el archivo de encabezado Ws2def.h. Tenga en cuenta que el archivo de encabezado Ws2def.h se incluye automáticamente en Winsock2.h y nunca se debe usar directamente.

Si se especifica un valor de 0 para ai_protocol, el autor de la llamada no desea especificar un protocolo y el proveedor de servicios elegirá el ai_protocol que se va a usar. En el caso de los protocolos distintos de IPv4 e IPv6, establezca ai_protocol en cero.

En la tabla siguiente se enumeran los valores comunes para el miembro ai_protocol , aunque muchos otros valores son posibles.

Valor Significado
IPPROTO_TCP
6
Protocolo de control de transmisión (TCP). Se trata de un valor posible cuando el miembro ai_family es AF_INET o AF_INET6 y el miembro ai_socktype está SOCK_STREAM.
IPPROTO_UDP
17
Protocolo de datagramas de usuario (UDP). Este es un valor posible cuando el miembro ai_family es AF_INET o AF_INET6 y el parámetro de tipo se SOCK_DGRAM.
IPPROTO_RM
113
Protocolo PGM para multidifusión confiable. Este es un valor posible cuando se AF_INET el miembro ai_family y el miembro ai_socktype es SOCK_RDM. En el Windows SDK publicado para Windows Vista y versiones posteriores, este valor también se denomina IPPROTO_PGM.
 

Si el miembro ai_family es AF_IRDA, el ai_protocol debe ser 0.

ai_addrlen

Tipo: size_t

Longitud, en bytes, del búfer al que apunta el miembro ai_addr .

ai_canonname

Tipo: PWSTR

Nombre canónico del host.

ai_addr

Tipo: struct sockaddr*

Puntero a una estructura de sockaddr . El miembro ai_addr en cada estructura ADDRINFOW devuelta apunta a una estructura de direcciones de socket rellenada. La longitud, en bytes, de cada estructura ADDRINFOW devuelta se especifica en el miembro ai_addrlen .

ai_next

Tipo: struct addrinfoW*

Puntero a la siguiente estructura de una lista vinculada. Este parámetro se establece en NULL en la última estructura addrinfoW de una lista vinculada.

Comentarios

La función GetAddrInfoW de Unicode usa la estructura addrinfoW para contener la información de dirección del host.

La estructura addrinfo es una versión ANSI de esta estructura utilizada por la función getaddrinfo de ANSI.

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

Tras una llamada correcta a GetAddrInfoW, se devuelve una lista vinculada de estructuras ADDRINFOW en el parámetro ppResult pasado a la función GetAddrInfoW . La lista se puede procesar siguiendo el puntero proporcionado en el miembro ai_next de cada estructura ADDRINFOW devuelta hasta que se encuentre un puntero NULL . En cada estructura ADDRINFOW 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 en cada estructura ADDRINFOW devuelta apunta a una estructura de direcciones de socket rellenada, la longitud de la cual se especifica en su miembro ai_addrlen .

Ejemplos

En el ejemplo de código siguiente se muestra cómo usar la estructura addrinfoW .

#ifndef UNICODE
#define UNICODE
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

int __cdecl wmain(int argc, wchar_t ** argv)
{
//--------------------------------
// Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    ADDRINFOW *result = NULL;
    ADDRINFOW *ptr = NULL;
    ADDRINFOW hints;

    DWORD dwRetval = 0;
    int i = 1;

    struct sockaddr_in *sockaddr_ipv4;
    struct sockaddr_in6 *sockaddr_ipv6;
//    LPSOCKADDR sockaddr_ip;

    wchar_t ipstringbuffer[46];

    // Validate the parameters
    if (argc != 3) {
        wprintf(L"usage: %ws <hostname> <servicename>\n", argv[0]);
        wprintf(L"       provides protocol-independent translation\n");
        wprintf(L"       from a host name to an IP address\n");
        wprintf(L"%ws example usage\n", argv[0]);
        wprintf(L"   %ws www.contoso.com 0\n", argv[0]);
        return 1;
    }
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }
//--------------------------------
// Setup the hints address info structure
// which is passed to the GetAddrInfoW() function
    memset(&hints, 0, sizeof (hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    wprintf(L"Calling GetAddrInfoW with following parameters:\n");
    wprintf(L"\tName = %ws\n", argv[1]);
    wprintf(L"\tServiceName (or port) = %ws\n\n", argv[2]);

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

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

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

        wprintf(L"GetAddrInfoW response %d\n", i++);
        wprintf(L"\tFlags: 0x%x\n", ptr->ai_flags);
        wprintf(L"\tFamily: ");
        switch (ptr->ai_family) {
        case AF_UNSPEC:
            wprintf(L"Unspecified\n");
            break;
        case AF_INET:
            wprintf(L"AF_INET (IPv4)\n");
            // the InetNtop function is available on Windows Vista and later
            sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
            wprintf(L"\tIPv4 address %ws\n",
                    InetNtop(AF_INET, &sockaddr_ipv4->sin_addr, ipstringbuffer,
                             46));

            // We could also use the WSAAddressToString function
            // sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
            // The buffer length is changed by each call to WSAAddresstoString
            // So we need to set it for each iteration through the loop for safety
            // ipbufferlength = 46;
            // iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
            //    ipstringbuffer, &ipbufferlength );
            // if (iRetval)
            //    wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError() );
            // else    
            //    wprintf(L"\tIPv4 address %ws\n", ipstringbuffer);
            break;
        case AF_INET6:
            wprintf(L"AF_INET6 (IPv6)\n");
            // the InetNtop function is available on Windows Vista and later
            sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
            wprintf(L"\tIPv6 address %ws\n",
                    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr,
                             ipstringbuffer, 46));

            // We could also use WSAAddressToString which also returns the scope ID
            // sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
            // The buffer length is changed by each call to WSAAddresstoString
            // So we need to set it for each iteration through the loop for safety
            // ipbufferlength = 46;
            //iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
            //    ipstringbuffer, &ipbufferlength );
            //if (iRetval)
            //    wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError() );
            //else    
            //    wprintf(L"\tIPv6 address %ws\n", ipstringbuffer);
            break;
        default:
            wprintf(L"Other %ld\n", ptr->ai_family);
            break;
        }
        wprintf(L"\tSocket type: ");
        switch (ptr->ai_socktype) {
        case 0:
            wprintf(L"Unspecified\n");
            break;
        case SOCK_STREAM:
            wprintf(L"SOCK_STREAM (stream)\n");
            break;
        case SOCK_DGRAM:
            wprintf(L"SOCK_DGRAM (datagram) \n");
            break;
        case SOCK_RAW:
            wprintf(L"SOCK_RAW (raw) \n");
            break;
        case SOCK_RDM:
            wprintf(L"SOCK_RDM (reliable message datagram)\n");
            break;
        case SOCK_SEQPACKET:
            wprintf(L"SOCK_SEQPACKET (pseudo-stream packet)\n");
            break;
        default:
            wprintf(L"Other %ld\n", ptr->ai_socktype);
            break;
        }
        wprintf(L"\tProtocol: ");
        switch (ptr->ai_protocol) {
        case 0:
            wprintf(L"Unspecified\n");
            break;
        case IPPROTO_TCP:
            wprintf(L"IPPROTO_TCP (TCP)\n");
            break;
        case IPPROTO_UDP:
            wprintf(L"IPPROTO_UDP (UDP) \n");
            break;
        default:
            wprintf(L"Other %ld\n", ptr->ai_protocol);
            break;
        }
        wprintf(L"\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        wprintf(L"\tCanonical name: %s\n", ptr->ai_canonname);
    }

    FreeAddrInfo(result);
    WSACleanup();

    return 0;
}

Requisitos

Requisito Value
Cliente mínimo compatible Windows Vista, Windows XP con SP2 [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows Server 2003 [solo aplicaciones de escritorio]
Encabezado ws2def.h (incluye Windows Server 2012, Windows 7 Windows Server 2008 R2)

Consulte también

GetAddrInfoEx

GetAddrInfoW

WSAEnumProtocols

addrinfo

addrinfoex

addrinfoex2

getaddrinfo

sockaddr