Condividi tramite


Struttura ADDRINFOA (ws2def.h)

La struttura addrinfo viene usata dalla funzione getaddrinfo per contenere le informazioni sull'indirizzo host.

Sintassi

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

Members

ai_flags

Tipo: int

Flag che indicano le opzioni usate nella funzione getaddrinfo .

I valori supportati per il membro ai_flags sono definiti nel file di intestazione Ws2def.h nel Windows SDK per Windows 7 e versioni successive. Questi valori sono definiti nel file di intestazione Ws2tcpip.h nel Windows SDK per Windows Server 2008 e Windows Vista. Questi valori sono definiti nel file di intestazione Ws2tcpip.h in Platform SDK per Windows Server 2003 e Windows XP. I valori supportati per il membro ai_flags possono essere una combinazione delle opzioni seguenti.

Valore Significato
AI_PASSIVE
0x01
L'indirizzo del socket verrà usato in una chiamata alla funzione di associazione .
AI_CANONNAME
0x02
Il nome canonico viene restituito nel primo membro ai_canonname .
AI_NUMERICHOST
0x04
Il parametro nodename passato alla funzione getaddrinfo deve essere una stringa numerica.
AI_ALL
0x0100
Se questo bit è impostato, viene effettuata una richiesta per gli indirizzi IPv6 e gli indirizzi IPv4 con AI_V4MAPPED.

Questa opzione è supportata in Windows Vista e versioni successive.

AI_ADDRCONFIG
0x0400
Getaddrinfo verrà risolto solo se è configurato un indirizzo globale. L'indirizzo di loopback IPv6 e IPv4 non è considerato un indirizzo globale valido.

Questa opzione è supportata in Windows Vista e versioni successive.

AI_V4MAPPED
0x0800
Se la richiesta getaddrinfo per gli indirizzi IPv6 ha esito negativo, viene effettuata una richiesta di servizio dei nomi per gli indirizzi IPv4 e questi indirizzi vengono convertiti in formato indirizzo IPv4 mappato a IPv6.

Questa opzione è supportata in Windows Vista e versioni successive.

AI_NON_AUTHORITATIVE
0x04000
Le informazioni sull'indirizzo possono essere provenienti da un provider di spazi dei nomi non autorevole.

Questa opzione è supportata solo in Windows Vista e versioni successive per lo spazio dei nomi NS_EMAIL .

AI_SECURE
0x08000
Le informazioni sull'indirizzo provengono da un canale sicuro.

Questa opzione è supportata solo in Windows Vista e versioni successive per lo spazio dei nomi NS_EMAIL .

AI_RETURN_PREFERRED_NAMES
0x010000
Le informazioni sull'indirizzo sono relative a un nome preferito per un utente.

Questa opzione è supportata solo in Windows Vista e versioni successive per lo spazio dei nomi NS_EMAIL .

AI_FQDN
0x00020000
Se viene specificato un nome flat (etichetta singola), getaddrinfo restituirà il nome di dominio completo in cui il nome verrà risolto. Il nome di dominio completo viene restituito nel membro ai_canonname .

Questo è diverso da AI_CANONNAME flag di bit che restituisce il nome canonico registrato in DNS, che può essere diverso dal nome di dominio completo risolto dal nome flat.

È possibile impostare solo uno dei bit di AI_FQDN e AI_CANONNAME . La funzione getaddrinfo avrà esito negativo se entrambi i flag sono presenti con EAI_BADFLAGS.

Questa opzione è supportata in Windows 7, Windows Server 2008 R2 e versioni successive.

AI_FILESERVER
0x00040000
Suggerimento per il provider dello spazio dei nomi su cui viene eseguita la query sul nome host in uno scenario di condivisione file. Il provider dello spazio dei nomi può ignorare questo hint.

Questa opzione è supportata in Windows 7, Windows Server 2008 R2 e versioni successive.

ai_family

Tipo: int

Famiglia di indirizzi. I valori possibili per la famiglia di indirizzi sono definiti nel file di intestazione Winsock2.h .

Nella Windows SDK rilasciata per Windows Vista e versioni successive, l'organizzazione dei file di intestazione è stata modificata e i possibili valori per la famiglia di indirizzi sono definiti nel file di intestazione Ws2def.h. Si noti che il file di intestazione Ws2def.h viene automaticamente incluso in Winsock2.h e non deve mai essere usato direttamente.

I valori attualmente supportati sono AF_INET o AF_INET6, ovvero i formati della famiglia di indirizzi Internet per IPv4 e IPv6. Altre opzioni per la famiglia di indirizzi (AF_NETBIOS per l'uso con NetBIOS, ad esempio) sono supportate se è installato un provider di servizi Windows Sockets per la famiglia di indirizzi. Si noti che i valori per la famiglia di indirizzi AF_ e le costanti della famiglia di protocolli PF_ sono identiche (ad esempio, AF_UNSPEC e PF_UNSPEC), quindi è possibile usare entrambe le costanti.

Nella tabella seguente sono elencati i valori comuni per la famiglia di indirizzi, anche se sono possibili molti altri valori.

Valore Significato
AF_UNSPEC
0
La famiglia di indirizzi non è specificata.
AF_INET
2
Famiglia di indirizzi IPv4 (Internet Protocol versione 4).
AF_NETBIOS
17
Famiglia di indirizzi NetBIOS. Questa famiglia di indirizzi è supportata solo se è installato un provider Windows Sockets per NetBIOS.
AF_INET6
23
Famiglia di indirizzi IPv6 (Internet Protocol versione 6).
AF_IRDA
26
Famiglia di indirizzi IrDA (Infrared Data Association). Questa famiglia di indirizzi è supportata solo se nel computer è installata una porta e un driver a infrarossi.
AF_BTH
32
Famiglia di indirizzi Bluetooth. Questa famiglia di indirizzi è supportata solo se è installata una scheda Bluetooth in Windows Server 2003 o versione successiva.

ai_socktype

Tipo: int

Tipo di socket. I valori possibili per il tipo di socket sono definiti nel file di intestazione Winsock2.h .

Nella tabella seguente sono elencati i valori possibili per il tipo di socket supportato per Windows Sockets 2:

Valore Significato
SOCK_STREAM
1
Fornisce flussi di byte sequenziati, affidabili, bidirezionali e basati sulla connessione con un meccanismo di trasmissione dei dati OOB. Usa il protocollo TCP (Transmission Control Protocol) per la famiglia di indirizzi Internet (AF_INET o AF_INET6). Se il membro ai_family è AF_IRDA, SOCK_STREAM è l'unico tipo di socket supportato.
SOCK_DGRAM
2
Supporta datagrammi, che non sono connectionless, buffer non affidabili di una lunghezza massima fissa (in genere piccola). Usa il protocollo UDP (User Datagram Protocol) per la famiglia di indirizzi Internet (AF_INET o AF_INET6).
SOCK_RAW
3
Fornisce un socket non elaborato che consente a un'applicazione di modificare l'intestazione del protocollo superiore successiva. Per modificare l'intestazione IPv4, è necessario impostare l'opzione IP_HDRINCL socket sul socket. Per modificare l'intestazione IPv6, l'opzione socket IPV6_HDRINCL deve essere impostata sul socket.
SOCK_RDM
4
Fornisce un datagramma di messaggi affidabile. Un esempio di questo tipo è l'implementazione del protocollo multicast generale pragmatico (PGM) in Windows, spesso definita programmazione multicast affidabile.
SOCK_SEQPACKET
5
Fornisce un pacchetto pseudo-flusso basato su datagrammi.
 

In Windows Sockets 2 sono stati introdotti nuovi tipi di socket. Un'applicazione può individuare dinamicamente gli attributi di ogni protocollo di trasporto disponibile tramite la funzione WSAEnumProtocols . Un'applicazione può quindi determinare le possibili opzioni di protocollo e tipo di socket per una famiglia di indirizzi e usare queste informazioni quando si specifica questo parametro. Le definizioni dei tipi di socket nei file di intestazione Winsock2.h e Ws2def.h verranno aggiornate periodicamente quando vengono definiti nuovi tipi di socket, famiglie di indirizzi e protocolli.

In Windows Sockets 1.1, gli unici tipi di socket possibili sono SOCK_DATAGRAM e SOCK_STREAM.

ai_protocol

Tipo: int

Tipo di protocollo. Le opzioni possibili sono specifiche per la famiglia di indirizzi e il tipo di socket specificati. I valori possibili per la ai_protocol sono definiti nei file di intestazione Winsock2.h e Wsrm.h .

Nella Windows SDK rilasciata per Windows Vista e versioni successive, l'organizzazione dei file di intestazione è stata modificata e questo membro può essere uno dei valori del tipo di enumerazione IPPROTO definito nel file di intestazione Ws2def.h. Si noti che il file di intestazione Ws2def.h viene automaticamente incluso in Winsock2.h e non deve mai essere usato direttamente.

Se per ai_protocol viene specificato un valore pari a 0, il chiamante non vuole specificare un protocollo e il provider di servizi sceglierà il ai_protocol da usare. Per i protocolli diversi da IPv4 e IPv6, impostare ai_protocol su zero.

Nella tabella seguente sono elencati i valori comuni per il membro ai_protocol anche se sono possibili molti altri valori.

Valore Significato
IPPROTO_TCP
6
TCP (Transmission Control Protocol). Si tratta di un valore possibile quando il membro ai_family è AF_INET o AF_INET6 e il membro ai_socktype è SOCK_STREAM.
IPPROTO_UDP
17
Protocollo UDP (User Datagram Protocol). Si tratta di un valore possibile quando il membro ai_family è AF_INET o AF_INET6 e il parametro di tipo è SOCK_DGRAM.
IPPROTO_RM
113
Protocollo PGM per multicast affidabile. Si tratta di un valore possibile quando il membro ai_family è AF_INET e il membro ai_socktype viene SOCK_RDM. Nella Windows SDK rilasciata per Windows Vista e versioni successive, questo valore viene chiamato anche IPPROTO_PGM.
 

Se il membro ai_family è AF_IRDA, il ai_protocol deve essere 0.

ai_addrlen

Tipo: size_t

Lunghezza, in byte, del buffer a cui punta il membro ai_addr .

ai_canonname

Tipo: char*

Nome canonico per l'host.

ai_addr

Tipo: sockaddr struct*

Puntatore a una struttura sockaddr . Il membro ai_addr in ogni struttura addrinfo restituita punta a una struttura di indirizzi socket compilata. La lunghezza, in byte, di ogni struttura addrinfo restituita viene specificata nel membro ai_addrlen .

ai_next

Tipo: struct addrinfo*

Puntatore alla struttura successiva in un elenco collegato. Questo parametro è impostato su NULL nell'ultima struttura addrinfo di un elenco collegato.

Commenti

La struttura addrinfo viene usata dalla funzione getaddrinfo ANSI per contenere le informazioni sull'indirizzo host.

La struttura addrinfoW è la versione di questa struttura usata dalla funzione Unicode GetAddrInfoW .

Le macro nel file di intestazione Ws2tcpip.h definiscono una struttura ADDRINFOT e un nome di funzione con maiuscole e minuscole getAddrInfo. La funzione GetAddrInfo deve essere chiamata con i parametri nodename e servname di un puntatore di tipo TCHAR e i parametri hint e res di un puntatore di tipo ADDRINFOT. Quando UNICODE o _UNICODE non è definito, ADDRINFOT viene definito per la struttura addrinfo e GetAddrInfo viene definito per getaddrinfo, la versione ANSI di questa funzione. Quando viene definito UNICODE o _UNICODE, ADDRINFOT viene definito alla struttura addrinfoW e GetAddrInfo è definito per GetAddrInfoW, la versione Unicode di questa funzione.

Al termine di una chiamata a getaddrinfo, viene restituito un elenco collegato di strutture addrinfo nel parametro res passato alla funzione getaddrinfo . L'elenco può essere elaborato seguendo il puntatore fornito nel membro ai_next di ogni struttura addrinfo restituita fino a quando non viene rilevato un puntatore NULL . In ogni struttura addrinfo restituita, i membri ai_family, ai_socktype e ai_protocol corrispondono ai rispettivi argomenti in una chiamata di funzione socket o WSASocket . Inoltre, il membro ai_addr in ogni struttura addrinfo restituita punta a una struttura di indirizzi socket compilata, la cui lunghezza viene specificata nel relativo membro ai_addrlen .

Supporto per getaddrinfo e lo struct addrinfo nelle versioni precedenti di Windows

La funzione getaddrinfo che usa la struttura addrinfo è stata aggiunta al Ws2_32.dll in Windows XP e versioni successive. La struttura addrinfo è definita nel file di intestazione Ws2tcpip.h incluso in Platform SDK rilasciato per Windows XP e versioni successive e la Windows SDK rilasciata per Windows Vista e versioni successive.

Per eseguire un'applicazione che usa la funzione getaddrinfo e la struttura addrinfo nelle versioni precedenti di Windows (Windows 2000), è necessario includere i file Ws2tcpip.h e Wspiapi.h . Quando viene aggiunto il file di inclusione Wspiapi.h , la funzione getaddrinfo viene definita alla funzione inline WspiapiGetAddrInfo nel file Wspiapi.h . In fase di esecuzione, la funzione WspiapiGetAddrInfo viene implementata in modo che se il Ws2_32.dll o il Wship6.dll (il file contenente getaddrinfo nell'anteprima della tecnologia IPv6 per Windows 2000) non include getaddrinfo, una versione di getaddrinfo viene implementata inline in base al codice nel file di intestazione Wspiapi.h . Questo codice inline verrà usato nelle piattaforme Windows precedenti che non supportano in modo nativo la funzione getaddrinfo .

Il protocollo IPv6 è supportato in Windows 2000 quando è installata l'anteprima della tecnologia IPv6 per Windows 2000. In caso contrario , il supporto getaddrinfo nelle versioni di Windows precedenti a Windows XP è limitato alla gestione della risoluzione dei nomi IPv4.

La funzione GetAddrInfoW che usa la struttura addrinfoW è la versione Unicode della funzione getaddrinfo e la struttura addrinfo associata. La funzione GetAddrInfoW è stata aggiunta alla Ws2_32.dll in Windows XP con Service Pack 2 (SP2). La funzione GetAddrInfoW e la struttura addrinfoW non possono essere usate nelle versioni di Windows precedenti a Windows XP con SP2.

Esempio

Nell'esempio di codice seguente viene illustrato l'uso della struttura addrinfo .


#undef UNICODE

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

// link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int __cdecl main(int argc, char **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult;
    INT iRetval;

    DWORD dwRetval;

    int i = 1;
    
    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;

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

    char ipstringbuffer[46];
    DWORD ipbufferlength = 46;

    // Validate the parameters
    if (argc != 3) {
        printf("usage: %s <hostname> <servicename>\n", argv[0]);
        printf("       provides protocol-independent translation\n");
        printf("       from an ANSI host name to an IP address\n");
        printf("%s example usage\n", argv[0]);
        printf("   %s www.contoso.com 0\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    //--------------------------------
    // Setup the hints address info structure
    // which is passed to the getaddrinfo() function
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    printf("Calling getaddrinfo with following parameters:\n");
    printf("\tnodename = %s\n", argv[1]);
    printf("\tservname (or port) = %s\n\n", argv[2]);
    
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
    dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
    if ( dwRetval != 0 ) {
        printf("getaddrinfo failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }

    printf("getaddrinfo returned success\n");
    
    // Retrieve each address and print out the hex bytes
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("\tIPv4 address %s\n",
                    inet_ntoa(sockaddr_ipv4->sin_addr) );
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                // the InetNtop function is available on Windows Vista and later
                // sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
                // printf("\tIPv6 address %s\n",
                //    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );
                
                // We use WSAAddressToString since it is supported on Windows XP and later
                sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
                // The buffer length is changed by each call to WSAAddresstoString
                // So we need to set it for each iteration through the loop for safety
                ipbufferlength = 46;
                iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
                    ipstringbuffer, &ipbufferlength );
                if (iRetval)
                    printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
                else    
                    printf("\tIPv6 address %s\n", ipstringbuffer);
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
        printf("\tSocket type: ");
        switch (ptr->ai_socktype) {
            case 0:
                printf("Unspecified\n");
                break;
            case SOCK_STREAM:
                printf("SOCK_STREAM (stream)\n");
                break;
            case SOCK_DGRAM:
                printf("SOCK_DGRAM (datagram) \n");
                break;
            case SOCK_RAW:
                printf("SOCK_RAW (raw) \n");
                break;
            case SOCK_RDM:
                printf("SOCK_RDM (reliable message datagram)\n");
                break;
            case SOCK_SEQPACKET:
                printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_socktype);
                break;
        }
        printf("\tProtocol: ");
        switch (ptr->ai_protocol) {
            case 0:
                printf("Unspecified\n");
                break;
            case IPPROTO_TCP:
                printf("IPPROTO_TCP (TCP)\n");
                break;
            case IPPROTO_UDP:
                printf("IPPROTO_UDP (UDP) \n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_protocol);
                break;
        }
        printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        printf("\tCanonical name: %s\n", ptr->ai_canonname);
    }

    freeaddrinfo(result);
    WSACleanup();

    return 0;
}

Requisiti

Requisito Valore
Client minimo supportato Windows 2000 Professional [solo app desktop]
Server minimo supportato Windows 2000 Server [solo app desktop]
Intestazione ws2def.h

Vedi anche

GetAddrInfoW

WSAEnumProtocols

addrinfoW

bind

getaddrinfo

sockaddr