Aby otworzyć serwer gniazda, potrzebujemy kilku ważnych informacji o serwerze, z którymi chcemy się połączyć, takie jak adres domeny, rodzina adresu, którego używa itp.
Ten proces połączenia wymaga użycia kilku funkcji, a wywołanie każdego z nich ma określoną kolejność, którą należy ściśle przestrzegać. Wiele z tych funkcji służy do pobierania danych z serwera, z którym chcesz się połączyć. Ich wyniki to niektóre z argumentów wejściowych dla kolejnej funkcji.
Argumenty te są deskryptorami i strukturami danych zawierającej informacje dotyczące klienta i serwera o niektórych warstwach, które składają się.
W tym Wskazówka Linux Artykuł, nauczysz się, jak korzystać z getAddrinfo () funkcja rozwiązania adresu IP nazwy hosta i uzyskania niezbędnych informacji w strukturach danych, których używane przez różne funkcje C do połączenia ze zdalnym serwerem.
Zobaczymy opis składni, argumentów i struktur wejściowych/wyjściowych, które składają się na tę funkcję, a także teoretyczne wyjaśnienie, jak ona działa. Następnie zastosujemy to, czego nauczyliśmy się w praktycznym przykładzie, który zawiera fragmenty kodu i obrazy, które pokazują, jak korzystać z getAddrinfo () funkcja w c.
Korzystanie z tej funkcji wymaga zrozumienia struktur danych, które składają się na jego argumenty wejściowe. Z tego powodu zawarliśmy specjalną sekcję w tym artykule, który opisuje jego skład, rodzaj danych jego członków, parametr ustalony przez każdy z nich oraz modyfikację tego parametru.
Składnia funkcji getAddrinfo () w języku c
int getAddrinfo (const char *node,
Const Char *Service,
const struct addrinfo *wskazówki,
struct addrinfo ** res);
Opis funkcji getAddrinfo () w języku c
getAddrinfo () Funkcja rozwiązuje adres IP domeny i wykonuje przekraczanie informacji z serwerem dla podstawowych danych potrzebnych do otwarcia gniazda i nawiązania z nim komunikacji.
Adres IP, który jest rozwiązywany przez tę funkcję, jest przechowywany w strukturach typu sockaddr, ten sam typ, który jest używany przez funkcje bind () i connect () w celu ustalenia połączenia.
Aby lepiej zrozumieć, jak działa getAddrinfo (), musimy wiedzieć, jakie są jego argumenty wejściowe. Poniżej znajduje się lista tych argumentów wraz z wyjaśnieniem funkcji, którą każdy z nich wykonuje w getAddrinfo ():
węzeł: Ciąg lub wskaźnik, który określa nazwę domeny lub adres IP, z którego chcemy uzyskać informacje. Jeśli węzeł jest nazwą hosta, getAddrinfo () Rozwiązuje się do swojego adresu IP. Ten argument wejściowy akceptuje nazwę IPv4, IPv6 lub domeny.
praca: Ciąg lub wskaźnik, który określa typ usługi lub numer portu, za pomocą którego należy podłączyć gniazdo. Ten argument wejściowy może być przekazywany jako zerowy, o ile węzeł określa prawidłową nazwę hosta lub adres.
poradnik: Ten argument wejściowy jest strukturą addrinfo Wpisz, gdzie każdy z jego członków określa nazwę domeny i rodzaj połączenia, który ma być wykonany z serwerem. Te parametry dostarczają informacji o, na przykład, protokołu transportu, wersji IP, której zamierzamy użyć itp. W ten sposób informacje dostarczane przez serwer są ukierunkowane na ten typ połączenia, jeśli to możliwe. Później zobaczymy sekcję o tej strukturze, poszczególne parametry ustanowione przez jej członków i jak skonfigurować połączenie za pośrednictwem.
RES: Ten argument jest strukturą typu addrinfo, w którym przechowywane są informacje zwracane przez serwer. Res zawiera strukturę i wskaźnik do tej struktury lub listę struktur typu sockaddr, które przechowują adres nazwy hosta, który jest wysyłany węzeł i rozwiązane przez serwer. Ta struktura zawiera ten sam typ informacji poradnik w swoich członkach, ale z danymi z serwera. Informacje te są następnie wykorzystywane jako argument wejściowy do funkcji BIND () i Connect () w celu ustalenia połączenia.
W przypadkach, w których serwer zwraca więcej niż jeden adres, każdy może być dostępny za pomocą AI_NEXT wskaźnik, który jest członkiem res Struktura.
Jeśli getAddrinfo () funkcja z powodzeniem uzyskuje informacje, zwraca 0. Jeśli wystąpi błąd, ta funkcja zwraca kod z listy zdefiniowanej w „NetDB.H ”nagłówek.
Później znajdziesz sekcję dotyczącą błędów podczas korzystania z tej funkcji i definicji z ich odpowiednimi reprezentacjami numerycznymi, które są zwracane przez getAddrinfo ().
getAddrinfo () Funkcja jest zdefiniowana w „NetDB.H ”nagłówek. Aby go użyć, musi być zawarty w naszym kodzie w następujący sposób:
#włączać
Jak rozwiązać adres IP domeny za pomocą funkcji getAddrinfo () w c
W tym przykładzie wyjaśnimy, jak rozwiązać adres IP domeny i uzyskać niezbędne parametry z serwera w strukturach addrinfo i sockaddr, aby ustanowić z nim połączenie klient-serwer.
Pierwszym krokiem jest zdefiniowanie struktur i zmiennych potrzebnych do argumentów wejściowych i wyjściowych getAddrinfo (). Następnie spójrzmy na definicję zmiennych, których użyjemy w tym przykładzie i właściwy sposób zadeklarowania addrinfo Struktury:
w terrorze;
Char HostName [100] = "www.Linuxhints.com ";
struct addrinfo wskazówki_1, *res_1;
błąd zmienna jest argumentem wyjściowym getAddrinfo (). Używamy go do wykrycia możliwych błędów. Nazwa hosta tablica znaków zawiera ciąg o nazwie domeny i jest argumentem wejściowym, węzeł.
wskazówki_1 „Sugeruje” serwerze typu połączenia, które chcemy wykonać. RES_1 jest strukturą, która getAddrinfo () Zwraca z danymi serwerów i adresem domeny.
Ważne jest, aby ustawić wszystkie parametry wskazówki_1 Struktura do zerowych znaków. W tym przykładzie używamy funkcji memset (), aby ustawić przestrzeń przeznaczoną do tej struktury na znak zerowy.
Po zdefiniowaniu zmiennych i struktur nazywamy getAddrinfo () funkcjonować i przejść Nazwa hosta tablica jako argument wejściowy, węzeł, z nazwą domeny, której adres IP chcemy uzyskać. W takim przypadku używamy adresu naszej strony internetowej - „Www .Linuxhint.com ”
W argumencie wejściowym praca, Możemy określić, że żądana usługa to „HTTP” lub numer portu 80, który jest taki sam.
Trzecie i czwarte argumenty wejściowe to struktury wskazówki_1 I res_1, odpowiednio.
Argument wyjściowy jest błąd którego używamy do ustalenia, czy getAddrinfo () wraca z błędami lub skutecznie wykonuje operację.
Jeśli getAddrinfo () powraca z powodzeniem, struktury wskazane przez res_1 zawierają adres IP odpowiadający określonej domenie i dowolne parametry serwera potrzebne przez funkcje BIND () i Connect () w Sockaddr Wpisz struktury, aby się z nim połączyć.
Aby dowiedzieć się, czy wystąpi błąd, wynika, że wynik w konsoli polecenia. Następnie widzimy pełny kod tego przykładu, który zawiera nagłówki, określa zmienne i struktury oraz wywołuje getAddrinfo () funkcjonować.
#włączać
#włączać
#włączać
int main ()
w terrorze;
Char HostName [100] = "www.Linuxhints.com ";
struct addrinfo wskazówki_1, *res_1;
memset (& inds_1, „\ 0”, sizeof (inds_1));
error = getAddrinfo (nazwa hosta, „80”, i wskazówki_1 i res_1);
printf ("\ nerror: %i \ n", błąd);
Jak widać na poniższym obrazie, funkcja getAddrinfo powraca bez błędów:
Jak przekonwertować adres IP zwrócony przez serwer w strukturze struktury Addrinfo na ciąg
W wielu przypadkach przydatne jest konwersja adresu IP zwracanego przez serwer, gdy funkcja getAddrinf () jest wywoływana do ciągu. Ten adres jest przechowywany w 14-elementowej tablicy znaków, SA_DATA, W strukturze Sockaddr, która jest członkiem struktury RES typu Addrinfo.
Chociaż adres jest przechowywany w szeregu elementów zwęglać Typ, nie mają formatu znaków, ale liczbowa reprezentacja liczb całkowitych od 0 do 255.
W rodzinie IP v4 pierwsza wartość SA_DATA tablica jest zawsze zerowa, a druga wartość to numer portu. Tak więc elementy, które musimy przekonwertować, to 2, 3, 4 i 5.
Wykonujemy konwersję za pomocą funkcji inet_ntop (). Ta funkcja przekształca liczby binarne w tablicy SA_DATA na znaki i zwraca je w tablicy IP.
Ponieważ bajty, które określają numer IP, zaczynają się od bajtu nr 2, nazywamy ten adres jako wskaźnik do SA_DATA w argumencie wejściowym SRC funkcji inet_ntop ().
#włączać
niepodpisany Char IP [50] = "";
if (error == 0)
inet_ntop (af_inet i res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf („Adres IP: %s \ n \ n”, ip);
Jeśli wstawiamy ten fragment na końcu kodu poprzedniego przykładu, widzimy adres IP odpowiadający nazwie hosta, który wysyłamy do serwera, aby rozwiązać jego adres.
#włączać
#włączać
#włączać
int main ()
int a;
niepodpisany char b [5] = "";
niepodpisany Char IP [50] = "";
w terrorze;
Char HostName [100] = "www.Linuxhints.com ";
struct addrinfo wskazówki_1, *res_1;
memset (& inds_1, „\ 0”, sizeof (inds_1));
error = getAddrinfo (nazwa hosta, „80”, i wskazówki_1 i res_1);
printf ("\ nerror: %i \ n", błąd);
#włączać
niepodpisany Char IP [50] = "";
if (error == 0)
inet_ntop (af_inet i res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf („Adres IP: %s \ n \ n”, ip);
Na poniższym rysunku widzimy adres IP odpowiadający nazwie hosta, który pobieramy ze struktury addrinfo res_1 i konwertujemy na ciąg dla inet_ntop ():
Struktura addrinfo
Członkowie addrinfo Struktura jest odpowiedzialna za poinformowanie serwera o niektórych parametrach gniazda do otwarcia. Te parametry są określone w strukturze, która jest wysyłana jako argumenty wejściowe w poradnik. Serwer odpowiada, wysyłając informacje przechowywane w podobnej strukturze, której wskaźnik jest wysyłany jako argument wejściowy w res.
Zwracane informacje to konfiguracja pasująca lub jest najbliżej konfiguracji sugerowanej w poradnik na podstawie możliwości serwera. Na przykład, jeśli chcesz utworzyć konfigurację adresów IPv6, nie wszystkie serwery mogą obsłużyć ten typ rodziny.
Następnie szczegółowo patrzymy na poszczególne elementy struktury i jakie ustawiają parametry.
Struktura addrinfo
int ai_flags; /* Flagi wejściowe. */
int ai_family; /* Rodzina protokołu dla gniazda. */
int ai_socktype; /* Typ gniazda. */
int ai_protocol; /* Protokół do gniazda. */
socklen_t ai_addrlen; /* Długość adresu gniazda. */
struct sockaddr *ai_addr; /* Adres gniazda dla gniazda. */
char *ai_cannonname; /* Kanoniczna nazwa lokalizacji serwisowej. */
struct addrinfo *ai_next; /* Wskaźnik do następnego na liście. */
;
Spójrzmy szczegółowo na następujące poszczególne pola struktury addrinfo i opcje parametrów dla każdego pola:
ai_flags: Są to flagi kontrolne, które są pogrupowane w liczbę całkowitą. Aby ustawić jeden z nich na 0 lub 1, musisz wykonać operowanie logiczne bitwiszy między liczbą całkowitą a maską, która zmienia tylko wybrane bity. W naszym artykule „Operatorzy bitowców w C” wyjaśniamy krok po kroku, jak wykonywać operacje logiczne za pomocą masek.
Następnie spójrzmy na fragment „NetDB.H ”nagłówek, w którym te flagi są zdefiniowane z krótkim opisem każdego z nich:
/* Możliwe wartości dla pola „AI_FLAGS” w strukturze „addrinfo”. */
# Zdefiniuj AI_PASSIVE 0x0001 // adres jest przeznaczony do „wiązania”.
# Zdefiniuj AI_canonname 0x0002 // żądanie nazwy kanonicznej.
# Zdefiniuj AI_NUMERICHOST 0x0004 // Nie używaj rozdzielczości nazwy.
# Zdefiniuj AI_V4mapped 0x0008 // adresy zmapowane IPv4.
# Zdefiniuj AI_ALL 0x0010 // Zwróć odwzorowane IPv4 i IPv6
# Zdefiniuj AI_ADDRCONFIG 0x0020 // Użyj konfiguracji tego hosta
// wybierać
// Zwracany typ adresu.
# ifdef __use_gnu
# Zdefiniuj AI_IDN 0x0040 // IDN ENCODE WEJŚCIE // w bieżącym regionie
// Zestaw znaków (kolacja)
// przed przyjrzeniem się.
# Zdefiniuj AI_Canoidn 0x0080 // Przetłumacz nazwę kanoniczną z
// Format IDN.
# Zdefiniuj AI_IDN_ALLOW_UNESSIGNED 0x0100 //
// punkty kodu Unicode.
# Zdefiniuj AI_IDN_USE_STD3_ASCII_RULES 0x0200 // Waliduj ciągami
// według
// STD3 Zasady.
Manipulowanie flagami bez pełnej wiedzy może prowadzić do błędów, które są trudne do zdiagnozowania. Dlatego wskazane jest użycie tego pola w jego domyślnej konfiguracji.
ai_family: Ta liczba całkowita określa jedną z dwóch opcji rodzinnych, które serwer powinien zwrócić. Opcje rodziny adresów to:
AF_INET dla adresów IPv4.
AF_INET6 dla adresów IPv6.
Af_unspec może zwrócić jedną z dwóch rodzin.
ai_socktype: Ta liczba całkowita ustawia protokół transportu dla gniazda. Opcje typu to:
Sock_stream dla protokołu TCP
Sock_dgram dla protokołu UDP
ai_addrlen: To pole wskazuje rozmiar adresu gniazda.
Ai_addr: W tej strukturze typu sockaddr adres gniazda jest przechowywany.
AI_NEXT: Jeśli serwer ma więcej niż jeden adres, zwraca wiele struktur typu sockaddr, każda z nich zawiera inny adres. AI_NEXT jest wskaźnikiem listy struktur, których można użyć do dostępu do każdej struktury.
Jak ustawić parametry gniazda w polach Addrinfo struct
Parametry struktury addrinfo muszą być ustawione przed wywołaniem getAddrinfo (). Możesz je zmienić w następujący sposób:
Nazwa struktury . pole = wartość;
Na przykład, jeśli chcemy wybrać rodzinę adresów IPv6 w strukturze RES_1 poprzedniego przykładu, musimy wykonać następujące czynności:
res_1 . ai_family = AF_INET6
Błędy zwrócone przez funkcję getAddrinfo () w języku c
Jeśli błąd występuje, gdy getAddrinfo () Funkcja jest wywoływana, zwraca wartość liczbową wskazującą, jaki jest błąd. Następnie widzimy fragment „netdb.H ”nagłówek, w którym zdefiniowane są te błędy i ich reprezentacja numeryczna.
/* Wartości błędów dla funkcji „getAddrinfo”. */
# Zdefiniuj EAI_BADFLAGS -1 // Niepoprawna wartość dla pola „AI_FLAGS”.
# Zdefiniuj eai_noname -2 // Nazwa lub usługa jest nieznana.
# Zdefiniuj EAI_AGAIN -3 // Tymczasowa awaria w rozdzielczości nazwy.
# Zdefiniuj EAI_FAIL -4 // Nieodpuszczalna awaria w nazwie Res.
# Zdefiniuj eai_family -6 // „ai_family” nie jest obsługiwana.
# Zdefiniuj eai_socktype -7 // 'ai_socktype' nie jest obsługiwany.
# Zdefiniuj EAI_Service -8 // Usługa nie obsługiwana AI_SockType '
# Zdefiniuj EAI_Memory -10 // Awaria alokacji pamięci.
# Zdefiniuj EAI_System -11 // Błąd systemu zwrócony w „Errno”.
# Zdefiniuj EAI_OVERFLOW -12 // Bufor argumentów.
# ifdef __use_gnu
# Zdefiniuj EAI_NOData -5 // Brak adresu powiązanego z imieniem.
# Zdefiniuj EAI_ADDRFAMILY -9 // Adres Family pod kątem nazwy nie jest obsługiwany.
# Zdefiniuj EAI_INPROGRESS -100 // Wniosek o przetwarzanie w toku.
# Zdefiniuj EAI_CANCELED -101 // żądanie anulowane.
# Zdefiniuj EAI_NOTCANCELED -102 // żądanie niecałe.
# Zdefiniuj EAI_ALLDONE -103 // Wszystkie dokonane żądania.
# Zdefiniuj EAI_INTR -104 // Przerwane przez sygnał.
# Zdefiniuj eai_idn_encode -105 // IDN kodowanie nieudane.
Wniosek
W tym Linux wskazówki Artykuł, wyjaśniliśmy, jak korzystać z getAddrinfo () funkcja rozwiązania adresu IP domeny i uzyskania niezbędnych informacji z serwera, aby otworzyć gniazdo i połączyć się z nim.
Przyjrzeliśmy się składni tej funkcji i opisaliśmy każdy z jej argumentów wejściowych, rodzaj użytych w nich danych i ich cel w funkcji. Aby pomóc Ci zrozumieć, jak poradzić sobie z tą funkcją, stworzyliśmy dwie specjalne sekcje wyjaśniające, w jaki sposób budowane są struktury addrinfo, jakie parametry wykonują każdy z jego członków i jak możesz je zmienić, aby skonfigurować połączenie.
Mamy nadzieję, że ten artykuł uznałeś. Więcej artykułów o języku C i Linux wskazówki, Użyj wyszukiwarki na naszej stronie internetowej.