2014-05-01 37 views
15

Da quello che ho capito struct addrinfo viene utilizzato per preparare la struttura dell'indirizzo del socket e struct sockaddr contiene le informazioni sull'indirizzo del socket. Ma cosa significa in realtà? struct addrinfo contiene un puntatore a struct sockaddr. Perché tenerli separati? Perché non possiamo combinare tutte le cose all'interno di sockaddr in addr_info?Qual è la differenza tra struct addrinfo e struct sockaddr

Sto solo indovinando qui, ma il motivo della separazione è di risparmiare spazio quando si superano le strutture? Ad esempio nella chiamata bind(), tutto ciò di cui ha bisogno è il numero di porta e l'indirizzo internet. Quindi entrambi sono raggruppati in una struct sockaddr. Quindi, possiamo semplicemente passare questa piccola struttura invece della più grande struttura addrinfo?

struct addrinfo { 
    int    ai_flags;  // AI_PASSIVE, AI_CANONNAME, etc. 
    int    ai_family; // AF_INET, AF_INET6, AF_UNSPEC 
    int    ai_socktype; // SOCK_STREAM, SOCK_DGRAM 
    int    ai_protocol; // use 0 for "any" 
    size_t   ai_addrlen; // size of ai_addr in bytes 
    struct sockaddr *ai_addr;  // struct sockaddr_in or _in6 
    char   *ai_canonname; // full canonical hostname 

    struct addrinfo *ai_next;  // linked list, next node 
}; 

struct sockaddr { 
    unsigned short sa_family; // address family, AF_xxx 
    char    sa_data[14]; // 14 bytes of protocol address 
}; 

risposta

12

struct addrinfo viene restituito da getaddrinfo(), e contiene, in caso di successo, una lista concatenata di tali struct s per un nome host e/o servizio specificato.

Il ai_addr membro non è in realtà un struct sockaddr, perché questo struct è solo un generico che contiene i membri comuni per tutti gli altri, ed è usato per determinare quale tipo di struct che effettivamente hanno. A seconda di ciò che si passa a getaddrinfo() e a quale funzione è stata rilevata, ai_addr potrebbe effettivamente essere un puntatore a struct sockaddr_in o struct sockaddr_in6 o qualsiasi altra cosa, a seconda di ciò che è appropriato per quella specifica voce di indirizzo. Questa è una buona ragione per cui vengono mantenuti "separati", perché quel membro potrebbe puntare a uno dei diversi tipi di struct s, cosa che non è riuscita a fare se si è tentato di codificare tutti i membri in struct addrinfo, perché quelli diversi struct s hanno membri diversi.

Questo è probabilmente il modo più semplice per ottenere queste informazioni se si dispone di un nome host, ma non è l'unico modo. Per una connessione IPv4, puoi compilare tu stesso una struttura struct sockaddr_in, se vuoi e hai i dati per farlo, ed evitare di passare attraverso il rigamarole di chiamare getaddrinfo(), che potresti dover aspettare se è necessario uscire in internet per raccogliere le informazioni per voi. Non è necessario utilizzare struct addrinfo.

+0

è getaddrinfo() anche più utile se si conosce solo l'hostname e non l'indirizzo IP dell'host? Perché sembra un po 'ripetitivo se sei il cliente (e conosci l'IP del server) e chiami getaddrinfo e invii l'indirizzo IP del server e getaddrinfo() restituisce una struttura addrinfo con tutti i dettagli che già conosci? questo commento deve semplicemente ripetere ciò che hai detto..sorry – user68212

+0

'getaddrinfo()' a volte è conveniente se hai l'indirizzo IP in una * stringa * - diciamo dopo che è stato inserito nella riga di comando. È possibile analizzarlo da soli e inserirlo nel formato integrale a 32 bit richiesto da 'struct sockaddr_in', ma a volte si potrebbe pensare che sia più facile lasciare che' getaddrinfo() 'lo faccia per te. Se hai già l'IP in un formato che potresti inserire in 'struct sockaddr_in', chiamare' getaddrinfo() 'sarebbe in genere piuttosto inutile. –

Problemi correlati