Funkcja recv w języku C

Funkcja recv w języku C

Język C oferuje kilka możliwości i korzystanie z różnych funkcji do wysyłania i odbierania danych nad gniazdem. Każdy z nich zapewnia inną właściwość lub ograniczenie. Jednak „gniazdo.H ”Nagłówek definiuje funkcję recv (), która jest specjalnie zaprojektowana do odczytu plików gniazda i zapewnia opcje odbierania trybu, czekającego itp., Uczynienie go najbardziej odpowiedniego do użytku w połączeniach.

W tym Wskazówka Linux Artykuł, nauczysz się, jak korzystać z recv () funkcjonować. Jedna z dwóch funkcji jest używana do wysyłania i odbierania danych przez gniazdo w języku C.

Przyjrzymy się składni tej funkcji i jej teoretycznego opisu tego, jak ona działa, argumenty wejściowe i wyjściowe oraz typ danych, który jest akceptowany przez każdy z nich.

Następnie zaimplementujemy to, czego nauczyliśmy się w praktycznym przykładzie z fragmentami kodowymi i obrazami, w których tworzymy aplikację konsolową, aby wysłać polecenia do serwera i odbierać odpowiedź z recv () funkcjonować.

Składnia funkcji recv () w języku c

ssize_t recv (int sockfd, void *buf, size_t len, int flagi);

Opis funkcji recv () w języku c

recv () Funkcja odbiera dane wysyłane przez gniazdo. Ta funkcja odbiera dane z gniazda, którego identyfikator jest ustawiony Sockfd. Otrzymane dane są przechowywane w buforze, na który wskazuje BUF którego rozmiar należy określić w Len Argument wejściowy. Wejście flagi są flagami kontrolnymi, które są zgrupowane w liczbie całkowitej, która konfiguruje, w jaki sposób ta funkcja odbiera dane za pośrednictwem gniazda.

Gdy recv () jest wywoływany i nie ma danych, które czekają w kolejce, program czeka, aż pojawi się nowy pakiet, a następnie wznawia wykonanie następnego wiersza kodu. Ten martwy czas można stłumić za pomocą funkcji puli (), aby zapytać, czy dane czekają na otrzymanie, unikając w ten sposób niepotrzebnych wywołań do funkcji recv ().

Kolejną możliwością jest włączenie flagi MSG _DontWait ustawienie odbioru nieoblokowania. Jeśli recv () funkcja powraca z powodzeniem, zwraca liczbę bajtów, które są odbierane w wyniku. Jeśli wystąpi błąd podczas odbioru, recv () zwraca -1, a konkretny kod tego błędu można pobrać za pośrednictwem errno Zmienna globalna.

Następnie szczegółowo przyjrzyjmy się poszczególnym argumentom wejściowym tej funkcji:

Sockfd: Ten argument jest liczbą całkowitą, która musi zawierać identyfikator gniazda, przez który dane są odbierane. Ten identyfikator jest przypisywany przez system podczas tworzenia gniazda i wynik zwracany przez funkcję Socket ().

BUF: Ten wpis jest wskaźnikiem do bufora, gdzie recv () przechowuje otrzymane dane. Bufor powinien być rozmiar według wielkości pakietów, które należy odbierać. Bufory 1025 bajtów są wystarczające do połączeń TCP.

Len: Ten argument jest typu size_t i mówi funkcję wielkości BUF odbieraj bufor.

Flagi: Ta liczba całkowita zawiera zestaw flag kontrolnych, które nadają funkcji bardzo przydatne właściwości. Wartości tych flag są określone przez maskę między tą liczbą całkowitą a wybraną flagą, stosując między nimi działanie lub logiczne. Wartości reprezentujące te flagi i ich definicje można znaleźć w „gniazdku.H ”nagłówek. Widzimy każdą z tych flag i krótki opis ich następujących:

MSG_OOB = 0x01 przetwarza dane poza pasmem.

MSG_PEEK = 0x02 Zerkają na komunikaty przychodzące.

MSG_CTRUNC = 0x08 Kontroluje dane utracone przed dostawą.

Msg_proxy = 0x10 dostarcza lub zapyta drugi adres.

Msg_trunc = 0x20 Zwraca rozmiar odebranego datagrama. Tylko UDP.

MSG_DONTWAIT = 0x40 Nieoblokowanie odrzucenia.

Msg_wailall = 0x100 czeka na pełne żądanie.

Funkcja recvc () jest zdefiniowana w folderze „SYS” w „gniazdku.H ”nagłówek. Musimy podać go w naszym pliku w następujący sposób:

#włączać

Jak odbierać dane za pośrednictwem gniazda z funkcją recv () w języku C

W tym przykładzie łączymy gniazdo do www.Google.com, Wyślij polecenia HTTP na serwer, odbieraj odpowiedź za pomocą recv () funkcja, a następnie wyświetl go w konsoli poleceń.

Pierwszą częścią tego przykładu jest connect_to () Funkcja… tworzy gniazdo TCP dla usługi HTTP, łączy go z „www.Google.com ”domeny i zwraca Socket_id Identyfikator gniazda. Ponieważ to wszystko, co musimy pokazać, jak recv () Działa, nie przejdziemy dalej do tej części.

Druga część jest główną funkcją, w której ze połączonym gniazdem wysyłamy polecenie do serwera z funkcją send (), a następnie otrzymujemy odpowiedź w buforze BUF za pomocą recv () funkcjonować.

Możesz zobaczyć „główny” kod tej aplikacji i wyjaśnienie każdego pokazanego w niej kroku na następującej ilustracji:

//Krok 1
#włączać
#włączać
#włączać
#włączać
#włączać
#włączać
#włączać
#włączać
int connect_to ();
int main ()
int socket_id;
Char Buffer [1025];
//Krok 2
socket_id = connect_to ();
//Krok 3
while (1)
printf („Wyślij polecenie HTTP. Aby wyjść na naciśnięcie ctrl+c \ n ”);
Walki (bufor, 1025, stdin);
Wyślij (socket_id, bufor, 1025, 0);
memset (i bufor, „\ 0”, 1025);
//Krok 4
recv (socket_id, bufor, 1025, 0);
// Krok 5
printf („%s \ n”, bufor);
memset (i bufor, „\ 0”, 1025);

// end Main


Krok 1: Tutaj dodajemy wymagane nagłówki, tworzymy główną funkcję i definiujemy Socket_id liczba całkowita, która jest identyfikatorem gniazda i 1025-element bufor[] tablica znaków, w których funkcje send () i recv () przechowują dane, które wysyłają i odbierają z serwera.

Krok 2: Po zdefiniowaniu zmiennych nazywamy connect_to () funkcjonować i przejść Socket_id identyfikator jako argument wyjściowy. Funkcja powraca z podłączonym gniazdem i jego identyfikatorem w Socket_id.

Krok 3: Z połączeniem gniazda i jego uchwytu tworzymy While (1) pętla, w której funkcja fgets () czeka na wprowadzenie przez użytkownika polecenia HTTP w konsoli poleceń.

Po wprowadzeniu polecenia jest ono wysyłane do serwera przez gniazdo identyfikowane przez Socket_id Korzystanie z funkcji send ().

Krok 4: Zadzwoń do recv () funkcja, aby uzyskać odpowiedź serwera. Podczas wywoływania funkcji recv () wysyłamy identyfikator gniazda, Socket_id, Jako pierwszy argument wejściowy. Jako drugie i trzecie argumenty wysyłamy bufor[] wskaźnik bufora i jego rozmiar w bajtach, w którym to przypadku ustawiamy rozmiar pakietów na 1025. W takim przypadku ustawiamy wpis flag na 0.

Krok 5: recv () Funkcja powraca, gdy kończy odbieranie pakietu. Otrzymane dane z serwera są wyświetlane na konsoli poleceń poprzez drukowanie bufor[] Zawartość z funkcją printf (). Funkcja memset () służy do wyczyszczenia bufora po jego użyciu przez funkcje send () i recv ().

Następnie widzimy główny kod i funkcję Connect_TO ().

//Krok 1
#włączać
#włączać
#włączać
#włączać
#włączać
#włączać
#włączać
#włączać
int connect_to ();
int main ()

int socket_id;
Char Buffer [1025];
//Krok 2
socket_id = connect_to ();
//Krok 3
while (1)
printf („Wyślij polecenie HTTP. Aby wyjść na naciśnięcie ctrl+c \ n ”);
Walki (bufor, 1025, stdin);
Wyślij (socket_id, bufor, 1025, 0);
memset (i bufor, „\ 0”, 1025);
//Krok 4
recv (socket_id, bufor, 1025, 0);
// Krok 5
printf („%s \ n”, bufor);
memset (i bufor, „\ 0”, 1025);

// end Main
/************************************************* **************/
/* funkcja Connect_to*/
int connect_to ()
int port = 80;
w terrorze;
int socket_id;
Char Buffer [1025];
struktury hostent *serwer;
struct sockaddr_in Client;
memset (i serwer, 0, sizeof (serwer));
server = GethostByName ("www.Google.com ”);
if (server == null)

printf („\ nerror otrzymuje dane domeny.\N");
zwrot 1;

Socket_id = Socket (af_inet, sock_stream, 0);
klient.sin_family = af_inet;
klient.sin_port = htons (port);
bcopy ((char *) serwer-> h_addr,
(char *) i klient.sin_addr.s_addr,
sizeof (server-> h_length));
error = connect (socket_id, (struct sockaddr *) i klient, sizeof (client));
if (błąd < 0)
printf („\ ncould nie ustanowienie połączenia z serwerem \ n”);
Zamknij (socket_id);
zwrot 1;

printf ("\ nconnect to: %s \ n", inet_ntoa (klient.sin_addr));
return socket_id;


Utwórz plik o nazwie „Przykład.c ”i zapisz go w„ Dokumentach ”. Skopiuj kod i wklej go tam. Zapisz i skompiluj kod w GCC z następującym poleceniem:

~ $ GCC Dokumenty/przykład.C -O Przykład


Następnie uruchom program z następującym poleceniem:

~ $ ./przykład


Aplikacja łączy się z „www.Google.com ”i czeka, aż wprowadzimy polecenie HTTP.


Na poniższym rysunku widzimy wysyłane polecenie HTTP GET i odpowiedź serwera, która jest pobierana przez recv () funkcja w bufor[].

Jak zidentyfikować błędy, które funkcja recv () może wygenerować w języku C

Błędy, które mogą wystąpić podczas korzystania z funkcji recv (), są zróżnicowane, od błędów sieciowych po niepoprawne rozmiary buforu. Definicje tych kodów i ich numeryczna reprezentacja można znaleźć w „Errno.H ”nagłówek w folderze„ ASM-Generic ”i można go odzyskać, uzyskując dostęp do errno liczba całkowita.

Z następującym fragmentem w kroku 4 poprzedniego kodu, dzwonimy recv () Funkcja z stanu IF. Gdy wystąpi błąd, wydrukowana jest komunikat, a następnie predefiniowana liczba, która identyfikuje błąd, który jest przechowywany w errno liczba całkowita:

//Krok 4
if (recv (socket_id, bufor, 1025, 0) < 0)
printf („błąd:%i”, errno);


Poniżej przedstawiono definicje błędów, które mogą być wygenerowane przez funkcję recv () i krótki opis każdego błędu:


Poniższy rysunek pokazuje błąd występujący podczas próby odbierania danych za pomocą nieistniejącego identyfikatora gniazda. Wynikowy błąd w errno jest równa 88 „Operacja gniazda na bezsprzewajku”.

Wniosek

W tym Wskazówka Linux Artykuł, wyjaśniliśmy, jak korzystać z funkcji recv () do odbierania danych na gnieździe. Przyjrzeliśmy się składni tej funkcji, a także opisowi tego, jak ona działa, argumenty wejściowe i wyjściowe oraz typy danych, które akceptują.

Aby zobaczyć, jak działa ta funkcja, utworzyliśmy aplikację konsoli, w której użyliśmy funkcji recv (), aby otrzymać odpowiedź z serwera przez gniazdo, które jest do niej podłączone. Pokazaliśmy również, jak zidentyfikować i klasyfikować niektóre z najczęstszych błędów podczas korzystania z tej funkcji.

Mamy nadzieję, że ten artykuł uznałeś. Aby uzyskać więcej artykułów na temat porad C Language i Linux, użyj wyszukiwarki na naszej stronie internetowej.