Getaddrinfo -funksjon på C -språk

Getaddrinfo -funksjon på C -språk

For å åpne en socket-klient-server, trenger vi litt viktig informasjon om serveren som vi ønsker å koble til, for eksempel domeneadressen, adressefamilien den bruker osv.

Denne tilkoblingsprosessen krever bruk av flere funksjoner, og samtalen til hver av disse har en spesifikk ordre som må følges strengt. Mange av disse funksjonene brukes til å hente dataene fra serveren du vil koble til. Resultatene deres er noen av inngangsargumentene for den påfølgende funksjonen.

Disse argumentene er beskrivelser og datastrukturer som inneholder klienten og serverspesifikk informasjon om noen av lagene som utgjør en nettverkstilkobling.

I dette Linux hint artikkel, du lærer hvordan du bruker getAddrinfo () Funksjon for å løse IP -adressen til et vertsnavn og innhente nødvendig informasjon i datastrukturene som de forskjellige C -funksjonene bruker for å koble til en ekstern server.

Vi vil se en beskrivelse av syntaks, argumenter og inngangs-/utgangsstrukturer som utgjør denne funksjonen, samt en teoretisk forklaring på hvordan den fungerer. Deretter vil vi bruke det vi lærte i et praktisk eksempel som inkluderer kodebiter og bilder som viser hvordan du bruker getAddrinfo () funksjon i c.

Å bruke denne funksjonen krever forståelse av datastrukturene som utgjør inngangsargumentene. Av denne grunn inkluderte vi en spesiell seksjon i denne artikkelen som beskriver dens sammensetning, typen data fra medlemmene, parameteren som er satt av hver av dem, og modifiseringen av denne parameteren.

Syntaks av getAddrinfo () -funksjon på C -språk

int getAddrinfo (const char *node,
const char *service,
const struct addrinfo *hint,
struct addrinfo ** res);

Beskrivelse av getAddrinfo () -funksjonen på C -språket

De getAddrinfo () Funksjonen løser IP -adressen til et domene og utfører en informasjonskryssing med serveren for de grunnleggende dataene som er nødvendig for å åpne en stikkontakt og etablere en kommunikasjon med den.

IP -adressen som er løst av denne funksjonen lagres i strukturer av sockaddr -type, den samme typen som brukes av Bind () og Connect () -funksjonene for å etablere tilkoblingen.

For bedre å forstå hvordan getAddrinfo () fungerer, må vi vite hva inngangsargumentene er. Følgende er en liste over disse argumentene sammen med en forklaring av funksjonen som hver av dem utfører innen getAddrinfo ():

Node: En streng, eller en peker til den, som spesifiserer domenenavnet eller IP -adressen som vi ønsker å få informasjonen fra. Hvis noden er et vertsnavn, getAddrinfo () løser seg til IP -adressen. Dette inngangsargumentet godtar en IPv4, IPv6 eller domenenavn.

service: En streng eller en peker til den som spesifiserer type tjeneste eller portnummer som kontakten skal kobles til. Dette inngangsargumentet kan sendes som null så lenge noden spesifiserer et gyldig vertsnavn eller adresse.

Tips: Dette inngangsargumentet er en struktur av addrinfo Skriv inn der hvert av medlemmene spesifiserer domenenavnet og typen tilkobling som skal gjøres til serveren. Disse parametrene gir informasjon om for eksempel transportprotokollen, IP -versjonen vi har tenkt å bruke osv. På denne måten er informasjonen som er gitt av serveren målrettet mot denne typen tilkoblinger, hvis mulig. Senere vil vi se et avsnitt om denne strukturen, de individuelle parametrene som er etablert av medlemmene, og hvordan du konfigurerer tilkoblingen gjennom dem.

res: Dette argumentet er en struktur av addrinfo -type der informasjonen som blir returnert av serveren er lagret. Res Inneholder en struktur og en peker til denne strukturen eller en liste over strukturer av sockaddr -type som lagrer adressen til vertsnavnet som sendes inn Node og løst av serveren. Denne strukturen inneholder samme informasjonstype hint i sine medlemmer, men med dataene fra serveren. Denne informasjonen blir deretter brukt som et inngangsargument til Bind () og Connect () -funksjonene for å etablere forbindelsen.

I tilfeller der serveren returnerer mer enn en adresse, kan hver få tilgang til AI_NEXT peker som er medlem av res struktur.

Hvis getAddrinfo () Funksjon innhenter informasjonen, den returnerer 0. Hvis det oppstår en feil, returnerer denne funksjonen koden fra en liste som er definert i “NetDB.h ”header.

Senere finner du en seksjon som omhandler feil når du bruker denne funksjonen og definisjonene med deres respektive numeriske representasjoner som returneres av GetAddrinfo ().

De getAddrinfo () Funksjonen er definert i “NetDB.h ”header. For å bruke den, må den inkluderes i koden vår som følger:

#inkludere

Hvordan løse IP -adressen til et domene ved hjelp av getAddrinfo () -funksjonen i C

I dette eksemplet vil vi forklare hvordan du løser IP-adressen til et domene og får de nødvendige parametrene fra serveren i Addrinfo- og Sockaddr-strukturer for å etablere en klient-serverforbindelse til den.

Det første trinnet er å definere strukturer og variabler som er nødvendige for inngangs- og utgangsargumentene til getAddrinfo (). La oss deretter se på definisjonen av variablene som vi vil bruke i dette eksemplet og riktig måte å erklære addrinfo strukturer:

int feil;
char hostname [100] = "www.Linuxhints.com ";
struct addrinfo hints_1, *res_1;


De feil Variabel er utgangsargumentet til getAddrinfo (). Vi bruker den til å oppdage mulige feil. De Vertsnavn Karakterarray inneholder strengen med domenenavnet og er inngangsargumentet, Node.

De hints_1 “Foreslår” til serveren den typen tilkobling vi ønsker å lage. RES_1 er strukturen som getAddrinfo () kommer tilbake med serverdata og domeneadresse.

Det er viktig at du setter alle parametrene til hints_1 struktur til null tegn. I dette eksemplet bruker vi memset () -funksjonen for å sette plassen som er tildelt denne strukturen til nullkarakter.

Når variablene og strukturene er definert, kaller vi getAddrinfo () funksjon og passere Vertsnavn Array som et inngangsargument, Node, med domenenavnet hvis IP -adresse vi ønsker å få. I dette tilfellet bruker vi adressen til nettstedet vårt - “Www .Linuxhint.com ”

I inngangsargumentet service, Vi kan spesifisere at den forespurte tjenesten er "http" eller portnummer 80 som er den samme.

Den tredje og fjerde inngangsargumentene er strukturene hints_1 og res_1, henholdsvis.

Utgangsargumentet er feil som vi bruker for å avgjøre om getAddrinfo () returnerer med feil eller utfører operasjonen vellykket.

Hvis getAddrinfo () returnerer vellykket, strukturene som er pekt på av res_1 Inneholder IP -adressen som tilsvarer det spesifiserte domenet og alle serverparametere som trengs av Bind () og Connect () -funksjonene i Sockaddr Skriv inn strukturer for å koble til den.

For å finne ut om det oppstår en feil, sender vi resultatet i kommandokonsollen. Deretter ser vi hele koden for dette eksemplet som inkluderer overskriftene, definerer variablene og strukturene og kaller getAddrinfo () funksjon.

#inkludere
#inkludere
#inkludere
int main ()

int feil;
char hostname [100] = "www.Linuxhints.com ";
struct addrinfo hints_1, *res_1;
memset (& hints_1, '\ 0', sizeof (hints_1));
error = getAddrinfo (hostname, "80", & hints_1, & res_1);
printf ("\ nerror: %i \ n", feil);


Som vi kan se i følgende bilde, returnerer GetAddrinfo -funksjonen uten feil:

Hvordan konvertere IP -adressen som returneres av serveren i en addrinfo -strukturstruktur til streng

I mange tilfeller er det nyttig å konvertere IP -adressen som returneres av serveren når getAddrinf () -funksjonen kalles til en streng. Denne adressen er lagret i 14-elementkarakterarray, sa_data, I sockaddr -strukturen som er medlem av res -strukturen av addrinfo -type.

Selv om adressen er lagret i en rekke elementer av røye Type, de har ikke noe karakterformat, men en numerisk representasjon av heltall fra 0 til 255.

I IP V4 -familien, den første verdien av sa_data Array er alltid null, og den andre verdien er portnummeret. Så elementene som vi trenger å konvertere er 2, 3, 4 og 5.

Vi utfører konverteringen ved hjelp av inet_ntop () -funksjonen. Denne funksjonen konverterer de binære tallene i SA_DATA -arrayen til tegn og returnerer dem i IP -matrisen.

Siden byte som spesifiserer IP -nummeret starter med byte nummer 2, omtaler vi denne adressen som en peker til SA_DATA i SRC -inngangsargumentet til INET_NTOP () -funksjonen.

#inkludere
usignert char ip [50] = "";
if (feil == 0)
inet_ntop (af_inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("IP -adresse: %s \ n \ n", ip);


Hvis vi setter inn dette fragmentet på slutten av koden for forrige eksempel, ser vi IP -en som tilsvarer vertsnavnet som vi sender til serveren for å løse adressen.

#inkludere
#inkludere
#inkludere
int main ()

int a;
usignert char b [5] = "";
usignert char ip [50] = "";
int feil;
char hostname [100] = "www.Linuxhints.com ";
struct addrinfo hints_1, *res_1;
memset (& hints_1, '\ 0', sizeof (hints_1));
error = getAddrinfo (hostname, "80", & hints_1, & res_1);
printf ("\ nerror: %i \ n", feil);
#inkludere
usignert char ip [50] = "";
if (feil == 0)
inet_ntop (af_inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("IP -adresse: %s \ n \ n", ip);


I den følgende figuren ser vi IP -adressen som tilsvarer vertsnavnet som vi henter fra Addrinfo res_1 -strukturen og konverterer til en streng for inet_ntop ():

Addrinfo struktur

Medlemmene av addrinfo Struktur er ansvarlig for å informere serveren om visse parametere for kontakten som skal åpnes. Disse parametrene er spesifisert i strukturen som sendes som inngangsargumenter i hint. Serveren svarer ved å sende informasjonen som er lagret i en lignende struktur hvis peker sendes som et inngangsargument i res.

Den returnerte informasjonen er en konfigurasjon som samsvarer med eller er nærmest konfigurasjonen som er foreslått i hint basert på serverens evner. Hvis du for eksempel vil lage en konfigurasjon for IPv6 -adresser, kan ikke alle servere håndtere denne typen familie.

Deretter ser vi i detalj på de enkelte elementene i strukturen og hvilke parametere de setter.

struktur addrinfo

int ai_flags; /* Inngangsflagg. */
int ai_family; /* Protokollfamilie for stikkontakt. */
int ai_socktype; /* Stikkontakt. */
int ai_protocol; /* Protokoll for stikkontakt. */
socklen_t ai_addrlen; /* Lengde på stikkontakt. */
struct sockaddr *ai_addr; /* Sokkeladresse for stikkontakt. */
char *ai_cannonname; /* Kanonisk navn for serviceplassering. */
struct addrinfo *ai_next; /* Peker til neste i listen. */
;


La oss ta en detaljert titt på følgende individuelle felt i Addrinfo -strukturen og parameteralternativene for hvert felt:

AI_FLAGS: Dette er kontrollflagg som er gruppert i et heltall. For å stille en av dem til 0 eller 1, må du utføre en bitvis logisk operasjon mellom heltallet og en maske som bare endrer de valgte bitene. I vår artikkel, "Bitwise Operators in C", forklarer vi trinn for trinn om hvordan du utfører de logiske operasjonene med masker.

Neste, la oss se på fragmentet av “NetDB.H ”overskrift der disse flaggene er definert med en kort beskrivelse av hver enkelt:

/* Mulige verdier for 'AI_FLAGS' felt i 'Addrinfo' -struktur. */
# Definer AI_PASSIV 0x0001 // Adresse er beregnet på 'bind'.
# Definer AI_CanonName 0x0002 // Forespørsel om kanonisk navn.
# Definer AI_Numerichost 0x0004 // Ikke bruk navnoppløsning.
# Definer AI_V4Mappet 0x0008 // IPv4 Mappedadresser.
# Definer AI_ALL 0x0010 // RETURN IPv4 MADD OG IPV6
# Definer AI_ADDRCONFIG 0x0020 // Bruk konfigurasjon av denne verten
// å velge
// returnert adressetype.
# ifdef __use_gnu
# Definer AI_IDN 0x0040 // IDN kode inngang // i det nåværende sted
// karaktersett (kolasjon)
// før du ser det opp.
# Definer AI_CANOIDN 0x0080 // Oversett kanonisk navn fra
// IDN -format.
# Definer ai_idn_allow_unassigned 0x0100 // Ikke avvis uten tilordnet
// Unicode -kodepoeng.
# Definer AI_IDN_USE_STD3_ASCII_RULES 0x0200 // Validate Strings
// i følge
// STD3 -regler.


Å manipulere flaggene uten full kunnskap kan føre til feil som er vanskelig å diagnostisere. Derfor anbefales det å bruke dette feltet i standardkonfigurasjonen.

ai_family: Dette heltallet spesifiserer ett av to adressefamiliealternativer som serveren skal returnere. Adressefamiliealternativene er:

Af_inet for IPv4 -adresser.

Af_inet6 for IPv6 -adresser.

AF_UNSPEC kan returnere en av de to familiene.

AI_SOCKTYPE: Dette heltallet setter transportprotokollen for kontakten. Typealternativene er:

SOCK_STREAM for TCP -protokoll

Sock_dgram for UDP -protokoll

ai_addrlen: Dette feltet indikerer størrelsen på sokkeladressen.

Ai_addr: I denne sockaddr -strukturen lagres adressen til kontakten.

AI_NEXT: Hvis serveren har mer enn en adresse, returnerer den flere strukturer av sockaddr -type, som hver inneholder en annen adresse. AI_NEXT er pekeren til listen over strukturer som du kan bruke for å få tilgang til hver struktur.

Hvordan du angir sokkelparametrene i feltene til Addrinfo struct

Parametrene til Addrinfo -strukturen må settes før du ringer GetAddrinfo (). Du kan endre dem på følgende måte:

Strukturnavn . felt = verdi;


Hvis vi for eksempel vil velge familien til IPv6 -adresser i RES_1 -strukturen i det forrige eksemplet, må vi gjøre følgende:

res_1 . ai_family = af_inet6

Feil returnert av getAddrinfo () -funksjonen på C -språket

Hvis det oppstår en feil når getAddrinfo () funksjon kalles, den returnerer en numerisk verdi som indikerer hva feilen er. Deretter ser vi et fragment av “NetDB.H ”overskrift der disse feilene og deres numeriske representasjon er definert.

/* Feilverdier for 'getAddrinfo' -funksjon. */
# Definer EAI_BADFLAGS -1 // Ugyldig verdi for 'AI_FLAGS' -felt.
# Definer EAI_NONAME -2 // Navn eller tjeneste er ukjent.
# Definer eai_again -3 // Midlertidig feil i navnoppløsningen.
# Definer EAI_FAIL -4 // Ikke -gjenvinnbar feil i Name Res.
# Definer eai_family -6 // 'AI_Family' ikke støttet.
# Definer EAI_SOCKTYPE -7 // 'AI_SOCKTYPE' ikke støttet.
# Definer EAI_Service -8 // Tjenesten støttet ikke AI_SOCKTYPE '
# Definer EAI_Memory -10 // Memory Allocation Feil.
# Definer EAI_SYSTEM -11 // Systemfeil returnert i 'Errno'.
# Definer eai_overflow -12 // Argumentbufferoverløp.
# ifdef __use_gnu
# Definer eai_nodata -5 // Ingen adresse tilknyttet navn.
# Definer eai_addrfamily -9 // adressefamilie for navn ikke støttet.
# Definer EAI_INPROGRESS -100 // Behandlingsforespørsel pågår.
# Definer eai_canceled -101 // Forespørsel kansellert.
# Definer eai_notcanceled -102 // Forespørsel ikke kansellert.
# Definer eai_alldone -103 // Alle forespørsler gjort.
# Definer EAI_INTR -104 // avbrutt av et signal.
# Definer eai_idn_encode -105 // IDN -koding mislyktes.

Konklusjon

I dette Linux hint Artikkel, vi forklarte hvordan vi bruker getAddrinfo () Funksjon for å løse IP -adressen til et domene og få nødvendig informasjon fra serveren for å åpne en stikkontakt og koble til den.

Vi så på syntaks for denne funksjonen og beskrev hvert av inngangsargumentene, typen data som ble brukt i dem og deres formål innenfor funksjonen i detalj. For å hjelpe deg med å forstå hvordan du håndterer denne funksjonen, opprettet vi to spesielle seksjoner som forklarer hvordan Addrinfo -strukturer er bygget, hvilke parametere gjør hver av medlemmene sine håndtak, og hvordan du kan endre dem for å konfigurere tilkoblingen.

Vi håper at du fant denne artikkelen nyttig. For flere artikler om C -språket og Linux hint, Bruk søkemotoren på vår hjemmeside.