Per aprire un server client socket, abbiamo bisogno di alcune informazioni importanti sul server a cui vogliamo connetterci come l'indirizzo del dominio, la famiglia dell'indirizzo che utilizza, ecc.
Questo processo di connessione richiede l'uso di diverse funzioni e la chiamata a ciascuno di queste ha un ordine specifico che deve essere seguito rigorosamente. Molte di queste funzioni vengono utilizzate per recuperare i dati dal server a cui si desidera connettersi. I loro risultati sono alcuni degli argomenti di input per la funzione successiva.
Questi argomenti sono descrittori e strutture di dati che contengono informazioni specifiche del client e del server su alcuni dei livelli che costituiscono una connessione di rete.
In questo Suggerimento Linux Articolo, imparerai come usare il getAddRinfo () funzione per risolvere l'indirizzo IP di un nome host e ottenere le informazioni necessarie nelle strutture di dati utilizzate da varie funzioni C per connettersi a un server remoto.
Vedremo una descrizione della sintassi, degli argomenti e delle strutture di input/output che compongono questa funzione e una spiegazione teorica di come funziona. Quindi, applicheremo ciò che abbiamo appreso in un esempio pratico che include frammenti di codice e immagini che mostrano come usare il getAddRinfo () funzione in c.
L'uso di questa funzione richiede una comprensione delle strutture di dati che costituiscono i suoi argomenti di input. Per questo motivo, abbiamo incluso una sezione speciale in questo articolo che descrive la sua composizione, il tipo di dati dei suoi membri, il parametro che è impostato da ciascuno di essi e la modifica di questo parametro.
Sintassi della funzione getAddRinfo () in lingua C
int getAddRinfo (nodo const char *,
const char *servizio,
const struct addrinfo *suggerimenti,
struct Addrinfo ** res);
Descrizione della funzione getAddRinfo () nella lingua C
IL getAddRinfo () La funzione risolve l'indirizzo IP di un dominio ed esegue un passaggio di informazioni con il server per i dati di base necessari per aprire una presa e stabilire una comunicazione con essa.
L'indirizzo IP che viene risolto da questa funzione è memorizzato in strutture di tipo Sockaddr, lo stesso tipo utilizzato dalle funzioni di bind () e connect () per stabilire la connessione.
Per capire meglio come funziona getAddrinfo (), dobbiamo sapere quali sono i suoi argomenti di input. Quello che segue è un elenco di questi argomenti insieme a una spiegazione della funzione che ciascuno di essi svolge all'interno di getAddRinfo ():
nodo: Una stringa, o un puntatore ad essa, che specifica il nome di dominio o l'indirizzo IP da cui vogliamo ottenere le informazioni. Se il nodo è un nome host, getAddRinfo () si risolve al suo indirizzo IP. Questo argomento di input accetta un nome IPv4, IPv6 o dominio.
servizio: Una stringa o un puntatore ad essa che specifica il tipo di servizio o il numero di porta attraverso il quale dovrebbe essere collegato il socket. Questo argomento di input può essere passato come null purché il nodo specifica un nome host o un indirizzo valido.
Suggerimenti: Questo argomento input è una struttura di Addrinfo Digita in cui ciascuno dei suoi membri specifica il nome di dominio e il tipo di connessione da stabilire al server. Questi parametri forniscono informazioni su, ad esempio, sul protocollo di trasporto, sulla versione IP che intendiamo utilizzare, ecc. In questo modo, le informazioni fornite dal server sono mirate a questo tipo di connessione, se possibile. Successivamente vedremo una sezione su questa struttura, i singoli parametri stabiliti dai suoi membri e come configurare la connessione attraverso di essi.
Res: Questo argomento è una struttura del tipo addrinfo in cui vengono memorizzate le informazioni che vengono restituite dal server. Res contiene una struttura e un puntatore a questa struttura o un elenco di strutture di tipo Sockaddr che memorizza l'indirizzo del nome host che viene inviato in nodo e risolto dal server. Questa struttura contiene lo stesso tipo di informazioni di Suggerimenti nei suoi membri, ma con i dati del server. Queste informazioni vengono quindi utilizzate come argomento di input per le funzioni di bind () e connect () per stabilire la connessione.
Nei casi in cui il server restituisce più di un indirizzo, è possibile accedere a ciascuno con ai_next puntatore che è membro del res struttura.
Se la getAddRinfo () La funzione ottiene correttamente le informazioni, restituisce 0. Se si verifica un errore, questa funzione restituisce il codice da un elenco definito in "Netdb.H ”intestazione.
Successivamente, troverai una sezione che tratta gli errori quando si utilizza questa funzione e le definizioni con le rispettive rappresentazioni numeriche che vengono restituite da getAddRinfo ().
IL getAddRinfo () La funzione è definita nel "netdb.H ”intestazione. Per usarlo, deve essere incluso nel nostro codice come segue:
#includere
Come risolvere l'indirizzo IP di un dominio utilizzando la funzione getAddRinfo () in c
In questo esempio, spiegheremo come risolvere l'indirizzo IP di un dominio e ottenere i parametri necessari dal server nelle strutture addrinfo e Sockaddr per stabilire una connessione client-server ad esso.
Il primo passo è definire le strutture e le variabili necessarie per gli argomenti di input e output di getAddRinfo (). Successivamente, esaminiamo la definizione delle variabili che useremo in questo esempio e il modo corretto per dichiarare il Addrinfo Strutture:
Errore int;
Char hostname [100] = "www.Linuxhints.com ";
struct addrinfo suggerimenti_1, *res_1;
IL errore La variabile è l'argomento di output di getAddRinfo (). Lo usiamo per rilevare i possibili errori. IL Nome host L'array di caratteri contiene la stringa con il nome di dominio ed è l'argomento di input, nodo.
IL suggerimenti_1 "Suggerisce" al server il tipo di connessione che vogliamo fare. REs_1 è la struttura che getAddRinfo () Ritorna con i dati del server e l'indirizzo di dominio.
È importante impostare tutti i parametri del suggerimenti_1 Struttura ai caratteri null. In questo esempio, utilizziamo la funzione Memset () per impostare lo spazio assegnato a questa struttura sul carattere nullo.
Una volta definite le variabili e le strutture, chiamiamo il getAddRinfo () funzione e passare il Nome host Array come argomento di input, nodo, con il nome di dominio il cui indirizzo IP vogliamo ottenere. In questo caso, utilizziamo l'indirizzo del nostro sito Web - “Www .Linuxhint.com "
Nell'argomento input servizio, Possiamo specificare che il servizio richiesto è "http" o il numero di porta 80 che è lo stesso.
Il terzo e il quarto argomento di input sono le strutture suggerimenti_1 E res_1, rispettivamente.
L'argomento dell'output è errore che usiamo per determinare se getAddRinfo () ritorna con errori o esegue l'operazione correttamente.
Se getAddRinfo () ritorna con successo, le strutture che sono indicate da res_1 contenere l'indirizzo IP corrispondente al dominio specificato e a tutti i parametri del server necessari dalle funzioni di bind () e connect () nelle Sockaddr Digitare le strutture per connettersi ad esso.
Per scoprire se si verifica un errore, emettiamo il risultato nella console di comando. Successivamente, vediamo il codice completo per questo esempio che include le intestazioni, definisce le variabili e le strutture e chiama il getAddRinfo () funzione.
#includere
#includere
#includere
int main ()
Errore int;
Char hostname [100] = "www.Linuxhints.com ";
struct addrinfo suggerimenti_1, *res_1;
memset (& hights_1, '\ 0', sizeof (suggerimenti_1));
errore = getAddRinfo (hostname, "80", & hights_1, & res_1);
printf ("\ nerror: %i \ n", errore);
Come possiamo vedere nella seguente immagine, la funzione getAddRinfo restituisce senza errori:
Come convertire l'indirizzo IP restituito dal server in una struttura di struttura addrinfo in stringa
In molti casi, è utile convertire l'indirizzo IP che viene restituito dal server quando la funzione getAddRinf () viene chiamata a una stringa. Questo indirizzo è archiviato nell'array di caratteri ad elementi a 14 elementi, sa_data, Nella struttura Sockaddr che è membro della struttura RES del tipo addrinfo.
Sebbene l'indirizzo sia archiviato in una serie di elementi di CHAR Tipo, non hanno un formato di carattere, ma una rappresentazione numerica di numeri interi da 0 a 255.
Nella famiglia IP V4, il primo valore del sa_data L'array è sempre zero e il secondo valore è il numero di porta. Quindi, gli elementi che dobbiamo convertire sono 2, 3, 4 e 5.
Eseguiamo la conversione usando la funzione Inet_ntop (). Questa funzione converte i numeri binari nell'array SA_Data ai caratteri e li restituisce nell'array IP.
Poiché i byte che specificano il numero IP iniziano con il byte numero 2, ci riferiamo a questo indirizzo come un puntatore a SA_DATA nell'argomento input SRC della funzione Inet_ntop ().
#includere
Char ip non firmato [50] = "";
if (errore == 0)
inet_ntop (af_inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("Indirizzo IP: %s \ n \ n", ip);
Se inseriamo questo frammento alla fine del codice dell'esempio precedente, vediamo l'IP corrispondente al nome host che inviamo al server per risolvere il suo indirizzo.
#includere
#includere
#includere
int main ()
int a;
char b [5] = "";
Char ip non firmato [50] = "";
Errore int;
Char hostname [100] = "www.Linuxhints.com ";
struct addrinfo suggerimenti_1, *res_1;
memset (& hights_1, '\ 0', sizeof (suggerimenti_1));
errore = getAddRinfo (hostname, "80", & hights_1, & res_1);
printf ("\ nerror: %i \ n", errore);
#includere
Char ip non firmato [50] = "";
if (errore == 0)
inet_ntop (af_inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("Indirizzo IP: %s \ n \ n", ip);
Nella figura seguente, vediamo l'indirizzo IP corrispondente al nome host che recuperiamo dalla struttura addrinfo Res_1 e convertiamo in una stringa per inet_ntop ()
Struttura addrinfo
I membri del Addrinfo La struttura è responsabile di informare il server su determinati parametri della presa da aprire. Questi parametri sono specificati nella struttura che viene inviata come argomenti di input in Suggerimenti. Il server risponde inviando le informazioni archiviate in una struttura simile il cui puntatore viene inviato come argomento di input in res.
Le informazioni restituite sono una configurazione che corrisponde o è più vicina alla configurazione che viene suggerita in Suggerimenti in base alle funzionalità del server. Ad esempio, se si desidera creare una configurazione per gli indirizzi IPv6, non tutti i server possono gestire questo tipo di famiglia.
Successivamente, esaminiamo in dettaglio i singoli elementi della struttura e quali parametri hanno impostato.
Struttura addrinfo
int ai_flags; /* Flag di input. */
int ai_family; /* Famiglia del protocollo per socket. */
int ai_socktype; /* Tipo di socket. */
int ai_protocol; /* Protocollo per socket. */
Socklen_t ai_addrlen; /* Lunghezza dell'indirizzo socket. */
struct Sockaddr *ai_addr; /* Indirizzo socket per socket. */
char *ai_cannonname; /* Nome canonico per la posizione del servizio. */
struct addrinfo *ai_next; /* Puntatore alla lista successiva nell'elenco. */
;
Diamo uno sguardo dettagliato ai seguenti singoli campi della struttura addrinfo e alle opzioni dei parametri per ciascun campo:
ai_flags: Queste sono flag di controllo che sono raggruppate in un numero intero. Per impostarne uno su 0 o 1, è necessario eseguire un'operazione logica bitwise tra l'intero e una maschera che cambia solo i bit selezionati. Nel nostro articolo, "Operatori bitwise in C", spieghiamo passo dopo passo su come eseguire le operazioni logiche con maschere.
Successivamente, guardiamo il frammento del "netdb.H ”Intestazione in cui queste bandiere sono definite con una breve descrizione di ciascuno:
/* Possibili valori per il campo 'AI_FLAGS' nella struttura 'addrinfo'. */
# Define Ai_Papave 0x0001 // L'indirizzo è destinato a 'Bind'.
# Define Ai_CanonName 0x0002 // Richiesta di nome canonico.
# define Ai_numerichost 0x0004 // Non usare la risoluzione dei nomi.
# Define AI_V4MAPP 0x0008 // IPv4 Mappati.
# Define Ai_all 0x0010 // return ipv4 mappato e ipv6
# Define AI_ADDRCONFIG 0x0020 // Usa la configurazione di questo host
// scegliere
// Tipo di indirizzo restituito.
# ifdef __use_gnu
# Define Ai_IDN 0x0040 // IDN ENCODE INPUT // Nella posizione corrente
// set di caratteri (colation)
// prima di guardarlo.
# Defini AI_CANOIDN 0x0080 // Traduci il nome canonico da
// formato idn.
# define Ai_idn_allow_unassigned 0x0100 // Non rifiutare non assegnato
// Punti del codice Unicode.
# define ai_idn_use_std3_ascii_rules 0x0200 // convalida stringhe
// secondo
// regole STD3.
Manipolare le bandiere senza piena conoscenza può portare a errori difficili da diagnosticare. Pertanto, è consigliabile utilizzare questo campo nella sua configurazione predefinita.
ai_family: Questo numero intero specifica una delle due opzioni di famiglia che il server dovrebbe restituire. Le opzioni della famiglia Indirizzo sono:
AF_INET per indirizzi IPv4.
AF_INET6 per indirizzi IPv6.
Af_unspec può restituire una delle due famiglie.
ai_socktype: Questo numero intero imposta il protocollo di trasporto per la presa. Le opzioni di tipo sono:
Sock_Stream per il protocollo TCP
Sock_Dgram per protocollo UDP
ai_addrlen: Questo campo indica la dimensione dell'indirizzo del socket.
Ai_addr: In questa struttura di tipo Sockaddr, viene memorizzato l'indirizzo della presa.
ai_next: Se il server ha più di un indirizzo, restituisce più strutture di tipo Sockaddr, ognuna contenente un indirizzo diverso. AI_NEXT è il puntatore dell'elenco delle strutture che è possibile utilizzare per accedere a ciascuna struttura.
Come impostare i parametri socket nei campi del ADDRINFO Struct
I parametri della struttura addrinfo devono essere impostati prima di chiamare il getAddRinfo (). Puoi cambiarli nel modo seguente:
Nome della struttura . campo = valore;
Ad esempio, se vogliamo selezionare la famiglia degli indirizzi IPv6 nella struttura Res_1 dell'esempio precedente, dobbiamo fare quanto segue:
res_1 . ai_family = af_inet6
Errori restituiti dalla funzione getAddRinfo () in lingua C
Se si verifica un errore quando il getAddRinfo () la funzione viene chiamata, restituisce un valore numerico che indica qual è l'errore. Successivamente, vediamo un frammento del "netdb.H ”intestazione dove sono definiti questi errori e la loro rappresentazione numerica.
/* Valori di errore per la funzione 'getAddRinfo'. */
# define eai_badflags -1 // valore non valido per il campo "ai_flag".
# define eai_noname -2 // nome o servizio è sconosciuto.
# define eai_again -3 // guasto temporaneo nella risoluzione dei nomi.
# Define EAI_FAIL -4 // Errore non recuperabile in nome Res.
# define eai_family -6 // 'ai_family' non supportato.
# define eai_socktype -7 // 'ai_socktype' non supportato.
# define eai_service -8 // servizio non supportato ai_socktype '
# Define EAI_MEMORY -10 // Errore di allocazione della memoria.
# Define EAI_SYSTEM -11 // Errore di sistema restituito in 'errno'.
# Define EAI_Overflow -12 // Overflow buffer argomento.
# ifdef __use_gnu
# define eai_nodata -5 // nessun indirizzo associato al nome.
# define eai_addrfamily -9 // Indirizzo famiglia per il nome non supportato.
# Define EAI_InProgress -100 // Richiesta di elaborazione in corso.
# define eai_canceled -101 // richiesta annullata.
# define eai_notcanceled -102 // richiesta non annullata.
# define eai_alldone -103 // tutte le richieste fatte.
# Define EAI_INTR -104 // interrotto da un segnale.
# define eai_idn_encode -105 // codifica idn non riuscita.
Conclusione
In questo Suggerimenti Linux Articolo, abbiamo spiegato come usare il getAddRinfo () funzione per risolvere l'indirizzo IP di un dominio e ottenere le informazioni necessarie dal server per aprire un socket e connettersi ad esso.
Abbiamo esaminato la sintassi di questa funzione e descritto ciascuno dei suoi argomenti di input, il tipo di dati utilizzati in essi e il loro scopo all'interno della funzione in dettaglio. Per aiutarti a capire come gestire questa funzione, abbiamo creato due sezioni speciali che spiegano come vengono costruite le strutture addrinfo, quali parametri gestiscono ciascuno dei suoi membri e come puoi cambiarli per configurare la connessione.
Speriamo che tu abbia trovato questo articolo utile. Per altri articoli sulla lingua C e Suggerimenti Linux, Si prega di utilizzare il motore di ricerca sul nostro sito Web.