Programowanie przy użyciu gniazdek



Podobne dokumenty
Literatura uzupełniająca: W. Richard Stevens, Programowanie zastosowań sieciowych w systemie Unix WNT 1998

Iteracyjny serwer TCP i aplikacja UDP

Podstawowe typy serwerów

Gniazda BSD. komunikacja bezpołączeniowa

Programowanie Sieciowe 1

2. Interfejs gniazd Gniazdo

Programowanie sieciowe

Gniazda. S. Samolej: Gniazda 1

Architektura typu klient serwer: przesyłanie pliku tekstowo oraz logowania do serwera za pomocą szyfrowanego hasła

Gniazda UDP. Bartłomiej Świercz. Łódź, 3 kwietnia Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda UDP

Klient-Serwer Komunikacja przy pomocy gniazd

Komunikacja międzyprocesowa. Krzysztof Banaś Systemy rozproszone 1

Tryb bezpołączeniowy (datagramowy)

Komunikacja sieciowa - interfejs gniazd

Gniazda BSD implementacja w C#

Programowanie aplikacji równoległych i rozproszonych. Wykład 4

Laboratorium z systemów operacyjnych. System plików - funkcje systemowe. Anna Wojak

Gniazda - Wstęp. Oprogramowanie systemów równoległych i rozproszonych. Sposób komunikacji. Domena adresowa. olas@icis.pcz.pl

ZESZYTY ETI ZESPOŁU SZKÓŁ W TARNOBRZEGU Nr 1 Seria: Teleinformatyka 2013

Gniazda BSD. Procesy w środowisku sieciowym. Gniazda podstawowe funkcje dla serwera. Gniazda podstawowe funkcje dla klienta

3. Identyfikacja. SKŁADNIA #include <sys/socket.h> int getpeername(int socket, struct sockaddr *addr, int *addrlen);

Transport. część 2: protokół TCP. Sieci komputerowe. Wykład 6. Marcin Bieńkowski

Instytut Teleinformatyki

1. Model klient-serwer

Transport. część 2: protokół TCP. Sieci komputerowe. Wykład 6. Marcin Bieńkowski

Projektowanie oprogramowania systemów KOMUNIKACJA SIECIOWA I SYSTEMY RPC

Aplikacja Sieciowa. Najpierw tworzymy nowy projekt, tym razem pracować będziemy w konsoli, a zatem: File->New- >Project

iseries Programowanie z użyciem gniazd

Krótkie wprowadzenie do korzystania z OpenSSL

Gniazda surowe. Bartłomiej Świercz. Łódź,9maja2006. Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda surowe

Architektura typu klient serwer: uproszczony klient POP3

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)

Beej s Guide to Network Programming

socket(int domain, int type, int protocol)

Gniazda BSD UNIWERSYTET GDAŃSKI WYDZIAŁ MATEMATYKI I FIZYKI. Jacek Nowicki

Warstwa transportowa. Warstwa transportowa. Enkapsulacja. Zapewnienie niezawodnego przesyłania danych /wg ISO/ Transmisja bezpołączeniowa

Sieci komputerowe. Zajęcia 3 c.d. Warstwa transportu, protokoły UDP, ICMP

Oprogramowanie komunikacyjne dla Internetu rzeczy Laboratorium nr 4 komunikacja unicastowa IPv6

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:

TCP - receive buffer (queue), send buffer (queue)

Komputery i Systemy Równoległe Jędrzej Ułasiewicz 1

PROTOKOŁY WARSTWY TRANSPORTOWEJ

Systemy rozproszone. Krzysztof Banaś Obliczenia równoległe 1

Komunikacja międzyprocesowa. Krzysztof Banaś Systemy rozproszone 1

Sieci komputerowe 1 DSRG

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

Sockety TCP/IP - podstawy. Sieci Komputerowe II Wyk ład 2

Schemat dla UDP. = możliwe zablokowanie aplikacji KLIENT SERWER. s=socket(...) bind(s,...) recvfrom(s,...) sendto(s,...) recvfrom(s,...

Temat zajęć: Obsługa systemu plików.

Mechanizmy pracy równoległej. Jarosław Kuchta

Serwer współbieżny połączeniowy

SYSTEMY CZASU RZECZYWISTEGO - VxWorks

Programowanie Programowanie z użyciem gniazd

Model OSI/ISO. Komputer B. Warstwy w modelu OSI aplikacji. aplikacji. prezentacji Komputer A. prezentacji. sesji. sesji. komunikacja wirtualna

Mechanizmy z grupy IPC

Poniższe funkcje opisane są w 2 i 3 części pomocy systemowej.

Programowanie Programowanie z użyciem gniazd

RPC. Zdalne wywoływanie procedur (ang. Remote Procedure Calls )

Od uczestników szkolenia wymagana jest umiejętność programowania w języku C oraz podstawowa znajomość obsługi systemu Linux.

5. Model komunikujących się procesów, komunikaty

Programowanie współbieżne i rozproszone

1.1 Przykład znajdowanie liczb pierwszych leżących w zadanym zakresie, tryb bezpołączeniowy

Programowanie sieciowe

Zadanie 2: transakcyjny protokół SKJ (2015)

W różnych systemach definicje mogą się różnić od powyższej. W linuxie sprobuj man 7 ip do wyswietlenia opisu.

IBM i Wersja 7.2. Programowanie Programowanie z użyciem gniazd

JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA. Marcin Lewandowski [ mlew@ippt.gov.pl ]

Podstawowe typy serwerów

IPC: Kolejki komunikatów

Temat zajęć: Mechanizmy IPC: kolejki komunikatów.

ZAAWANSOWANE BAZY DANYCH I HURTOWNIE DANYCH MySQL, PHP

Tworzenie aplikacji rozproszonej w Sun RPC

Zdalne wywołanie procedur. Krzysztof Banaś Systemy rozproszone 1

76.Struktura oprogramowania rozproszonego.

Instytut Teleinformatyki

Tunelowanie, kapsułkowanie, XDR. 1. Transmisja tunelowa i kapsułkowanie serwery proxy. 2. Zewnętrzna reprezentacja danych XDR.

Architektury systemów rozproszonych LABORATORIUM. Ćwiczenie 1

Kolejki FIFO (łącza nazwane)

1 Moduł Diagnostyki Sieci

Aplikacja Sieciowa wątki po stronie klienta

Sieci komputerowe. Wykład 5: Warstwa transportowa: TCP i UDP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

TIN Techniki Internetowe zima

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Na podstawie: Kirch O., Dawson T. 2000: LINUX podręcznik administratora sieci. Wydawnictwo RM, Warszawa. FILTROWANIE IP

Komunikacja z użyciem gniazd aplikacje klient-serwer

Routing. część 1: adresowanie. Sieci komputerowe. Wykład 2. Marcin Bieńkowski

Wykład 3 / Wykład 4. Na podstawie CCNA Exploration Moduł 3 streszczenie Dr inż. Robert Banasiak

ZiMSK. mgr inż. Artur Sierszeń mgr inż. Łukasz Sturgulewski ZiMSK 1

Przykład aplikacji UDP

PBS. Wykład Organizacja zajęć. 2. Podstawy obsługi urządzeń wykorzystywanych podczas laboratorium.

Akademickie Centrum Informatyki PS. Wydział Informatyki PS

1 Sposób zaliczenia przedmiotu

Routing. część 3: wewnątrz routera. Sieci komputerowe. Wykład 4. Marcin Bieńkowski

Routing. część 3: wewnątrz routera. Sieci komputerowe. Wykład 4. Marcin Bieńkowski

Routing. część 3: wewnątrz routera. Sieci komputerowe. Wykład 4. Marcin Bieńkowski

Bezpieczeństwo Usług Sieciowych SSL API. dr inż. Tomasz Surmacz. 28 listopada 2011

Oprogramowanie systemów równoległych i rozproszonych. Wykład 6

Problemy techniczne SQL Server

Transkrypt:

Programowanie przy użyciu gniazdek Gniazdo (ang. socket) pojęcie abstrakcyjne reprezentujące dwukierunkowy punkt końcowy połączenia. Dwukierunkowość oznacza możliwość wysyłania i przyjmowania danych. Wykorzystywane jest przez aplikacje do komunikowania się przez sieć w ramach komunikacji międzyprocesowej. Podstawowa biblioteka w systemie Linux/UNIX zawierająca funkcje do obsługi gniazd to socket.h. Funkcja socket(...) int socket(int domain,int type, int protocol) Funkcja służąca do tworzenia gniazda. domain rodzina protokołów (domena komunikacyjna), które będą wykorzystywane do komunikacji. type rodzina protokołów (domena komunikacyjna), które będą wykorzystywane do komunikacji. protocol rodzina protokołów (domena komunikacyjna), które będą wykorzystywane do komunikacji. Zmienna domain może przyjmować następujące wartości: AF_UNIX, PF_LOCAL lokalna komunikacja AF_INET protokół IPv4 AF_INET6 protokół IPv6 AF_IPX protokół IPX AF_APPLETALK Appletalk AF_NETLINK komunikacja pomiędzy modułami kernela a procesami przestrzeni użytkownika oraz wiele innych (więcej informacji można uzyskać na stronach podręcznika man socket) W systemach Linux/UNIX Zmienna type może przyjmować następujące wartości: SOCK_STREAM gniazdo strumieniowe SOCK_DGRAM gniazdo datagramowe SOCK_RAW w tym przypadku, wprawdzie kompilator nie zgłosi błędu, ale utworzy gniazdo typu SOCK_DGRAM

Ostatni z parametrów protocol jest zwykle ustawiany na 0. Ma on zastosowanie w przypadku zastosowania niektórych protokołów transmisji. Wartości zwracane przez funkcję socket: W przypadku powodzenia funkcja zwraca identyfikator nowoutworzonego gniazda, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu). EACCES brak uprawnień do tworzenia gniazda EAFNOSUPPORT użyto rodziny adresów, które nie są wspierane EINVAL użyto nieznanego protokołu lub rodziny protokołów EMFILE przepełniona tablica deskryptorów procesu ENFILE osiągnięta została dozwolona maksymalna liczba otwartych plików ENOBUFS lub ENOMEM brak pamięci EPROTONOSUPPORT wartości protocol i type niedozwolone w danej dziedzinie Wywołanie funkcji socket: Tak więc, aby utworzyć gniazdo wykorzystujące do komunikacji protokół TCP należy wywołać funkcję socket z następującymi parametrami socket(af_inet,sock_stream, 0) oraz socket(af_inet,sock_dgram, 0) dla protokołu UDP. Funkcja bind(...) int bind(int sockfd, struct sockaddr *my_addr, int addrlen) Funkcja nadaje gniazdu lokalny adres. my_addr struktura przechowująca lokalny adres addrlen wielkość struktury my_addr Wartości zwracane przez funkcję bind: W przypadku powodzenia funkcja zwraca 0, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu).

EBADF sockfd nie jest prawidłowym deskryptorem EINVAL gniazdo jest już przywiązane do adresu EACCES adres jest chroniony, a użytkownik nie jest superużytkownikiem ENOTSOCK argument jest deskryptorem pliku, a nie gniazda Wywołanie funkcji bind: my_addr.sin_family = AF_INET; my_addr.sin_port = htons(5432); //wybranie portu 5432 lub my_addr.sin_port = htons(0); // wybierz losowo nieużywany port my_addr.sin_addr.s_addr = INADDR_ANY; //gniazdo będzie przywiązane do wszystkich adresów lub my_addr.sin_addr.s_addr = inet_addr( 10.64.104.227 ); //gniazdo będzie przywiązane tylko do tego adresu memset(&(my_addr.sin_zero), '\0', 8); // wyzeruj resztę struktury bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr) Funkcja connect(...) int connect(int sockfd, struct sockaddr *serv_addr, int addrlen) Funkcja inicjalizująca połączenia poprzez gniazdo. serv_addr struktura przechowująca adres serwera addrlen wielkość struktury my_addr Wartości zwracane przez funkcję connect: W przypadku powodzenia funkcja zwraca 0, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu). EBADF sockfd nie jest prawidłowym deskryptorem EFAULT adres struktury gniazda znajduje się poza przestrzenią adresową użytkownika ENOTSOCK deskryptor nie jest związany z gniazdem EINVAL gniazdo jest już przywiązane do adresu EISCONN gniazdo już jest połączone. ECONNREFUSED Żaden serwer nie nasłuchuje na zdalnym adresie.

ETIMEDOUT Przeterminowanie próby połączenia. Serwer może być zbyt zajęty, aby przyjmować nowe połączenia. Dla gniazd IP czas przeterminowania może być bardzo długi, gdy na serwerze włączone są syncookies". ENETUNREACH sieć jest nieosiągalna. EADDRINUSE adres lokalny już jest wykorzystywany. EINPROGRESS gniazdo jest nieblokujące, a połączenie nie może zostać zrealizowane natychmiast. EALREADY gniazdo jest nieblokujące, a poprzednia próba połączenia nie została zakończona. EAGAIN brak wolnych portów lokalnych, lub brak wpisów w buforze marszrutowym. EAFNOSUPPORT przekazany adres miał prawidłowej rodziny adresów w swoim polu sa_family. EACCES, EPERM użytkownik próbował podłączyć się do adresu rozgłoszeniowego (broadcast) bez włączonego znacznika broadcast dla gniazda lub też połączenie nie udało się z powodu lokalnej reguły firewalla. Wywołanie funkcji connect: serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(2233); // port na którym działa serwer serv_addr.sin_addr.s_addr = inet_addr( 10.64.104.221 ); //adres serwera memset(&(serv_addr.sin_zero), '\0', 8); // wyzeruj resztę struktury connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)); Funkcja listen(...) int listen(int sockfd, int backlog) Funkcja rozpoczynająca nasłuchiwanie na połączenia na gnieździe. backlog maksymalna liczba połączeń (długość kolejki) oczekujących na obsługę Wartości zwracane przez funkcję listen: W przypadku powodzenia funkcja zwraca 0, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu). EADDRINUSE adres lokalny już jest wykorzystywany. EBADF sockfd nie jest prawidłowym deskryptorem ENOTSOCK deskryptor nie jest związany z gniazdem

Funkcja accept(...) int accept(int sockfd, void *addr, int *addrlen) Funkcja przyjmująca połączenia na gnieździe. addr struktura, do której zapisany zostanie adres podłączanego klienta addrlen wielkość struktury my_addr Wartości zwracane przez funkcję accept: W przypadku powodzenia funkcja zwraca identyfikator gniazda dla nowego połączenia, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu). EAGAIN lub EWOULDBLOCK gniazdo jest zaznaczone jako nieblokujące a brak jest połączeń, które mogłyby zostać przyjęte. EBADF deskryptor jest nieprawidłowy. ENOTSOCK deskryptor odnosi się do pliku, zamiast do gniazda. EOPNOTSUPP przekazane gniazdo nie jest typu SOCK_STREAM. EINTR funkcja systemowa została przerwana wskutek odebrania sygnału przed prawidłowym nawiązaniem połączenia. ECONNABORTED połączenie zostało przerwane. EINVAL gniazdo nie nasłuchuje połączeń. EMFILE osiągnięte zostało ograniczenie liczby otwartych deskryptorów plików dla procesu. ENFILE osiągnięte zostało systemowe ograniczenie liczby otwartych deskryptorów plików. EFAULT parametr addr nie znajduje się w przestrzeni adresowej dostępnej do zapisu dla użytkownika. ENOBUFS, ENOMEM jest niedostateczna ilość wolnej pamięci. Oznacza to zazwyczaj, że istnieje ograniczenie dla przydzielania pamięci na bufory gniazd, nie zaś że zabrakło pamięci w systemie. EPROTO wystąpił błąd protokołu. EPERM reguły firewalla zabraniają połączenia. Funkcje send(...), sendto(...), recv(...), recvfrom(...)

Prototypy: int send ( int sockfd, char *buff, int nbytes, int flags ); int sendto ( int sockfd, char *buff, int nbytes, int flags, struct sockaddr *to, int addrlen ); int recv ( int sockfd, char *buff, int nbytes, int flags ); int recvfrom ( int sockfd, char *buff, int nbytes, int flags, struct sockaddr *from, int addrlen ); Funkcja wysyłające i odbierające komunikaty. buff bufor nbytes długość komunikatu w buforze flags zwykle jest równy zero, ale może być kombinacją wartości MSG_OOB, MSG_PEEK oraz MSG_DONTROUTE to/from struktura z adresem odbiorcy/nadawcy addrlen wielkość struktury to/from Wartości zwracane przez funkcję accept: W przypadku powodzenia funkcja zwraca identyfikator gniazda dla nowego połączenia, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu). EAGAIN lub EWOULDBLOCK gniazdo jest zaznaczone jako nieblokujące a brak jest połączeń, które mogłyby zostać przyjęte. EBADF deskryptor jest nieprawidłowy. ENOTSOCK deskryptor odnosi się do pliku, zamiast do gniazda. EOPNOTSUPP przekazane gniazdo nie jest typu SOCK_STREAM. EINTR funkcja systemowa została przerwana wskutek odebrania sygnału przed prawidłowym nawiązaniem połączenia. ECONNABORTED połączenie zostało przerwane. EINVAL gniazdo nie nasłuchuje połączeń. EMFILE osiągnięte zostało ograniczenie liczby otwartych deskryptorów plików dla procesu. ENFILE osiągnięte zostało systemowe ograniczenie liczby otwartych deskryptorów plików. EFAULT parametr addr nie znajduje się w przestrzeni adresowej dostępnej do zapisu dla użytkownika. ENOBUFS, ENOMEM jest niedostateczna ilość wolnej pamięci. Oznacza to zazwyczaj, że istnieje ograniczenie dla przydzielania pamięci na bufory gniazd, nie zaś że zabrakło pamięci w systemie. EPROTO wystąpił błąd protokołu. EPERM reguły firewalla zabraniają połączenia.

Funkcja close(...) int close(int sockfd) Funkcja zamykająca gniazdo. Wartości zwracane przez funkcję close: W przypadku powodzenia funkcja zwraca 0, natomiast w przypadku błędu zwracana jest wartość 1 oraz ustawiana jest wartość zmiennej errno (zmienna opisująca typ błędu). EBADF deskryptor jest nieprawidłowy. EINTR funkcja systemowa została przerwana przez sygnał. EIO wystąpił błąd wejścia/wyjścia

Serwer socket(...) bind(...) listen(...) accept(...) blokuje a do po czenia z klientem recv(...) przetwarza danie send(...) nawi zanie po czenia dane ( danie) dane (odpowied ) Klient socket(...) connect(...) send(...) recv(...) Użycie funkcji systemowych w protokole połączeniowym. Serwer socket(...) bind(...) recvfrom(.) Klient blokuje a do otrzymania danych od klienta socket(...) bind(...) przetwarza danie sendto(...) dane ( danie) dane (odpowied ) sendto(...) recvfrom(.) Użycie funkcji systemowych w protokole bezpołączeniowym.

Przykład prostej aplikacji z wykorzystaniem gniazdek Jest to namiastka serwera usługi echo działającej z wykorzystaniem protokołu TCP. Aplikacja oczekuje na przesłanie od klienta komunikatu, a następnie odsyła ten sam komunikat z powrotem, po czym kończy działanie. #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <memory.h> #define PORT 7007 int main() int gniazdo, gniazdo2; struct sockaddr_in adres; struct sockaddr_in adres_zew; char buf[256]; int nbytes, addrlen; int yes=1; char* aa; if ( ( gniazdo = socket(af_inet, SOCK_STREAM, 0) ) == -1 ) perror("socket Error"); exit(1); adres.sin_family=af_inet; adres.sin_port=htons(port); adres.sin_addr.s_addr=inaddr_any; memset(&(adres.sin_zero),'\0',8); setsockopt(gniazdo, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); if( bind( gniazdo, (struct sockaddr*)&adres, sizeof(adres)) == -1) perror("bind Error"); close(gniazdo); exit(1); if( listen(gniazdo, 10) == -1 ) perror("listen Error"); close(gniazdo); exit(1); addrlen = sizeof(struct sockaddr_in); gniazdo2 = accept (gniazdo, (struct sockaddr *)&adres_zew, &addrlen ); printf("podlaczenie klienta z adresu %s\n", inet_ntoa(adres_zew.sin_addr)); if( gniazdo2 == -1 ) perror("accept Error"); close(gniazdo);

exit(1); if((nbytes=recv(gniazdo2, buf, sizeof(buf), 0 )) <= 0 ) perror("recv Error"); close (gniazdo2); close (gniazdo); exit(1); printf("komunikat od klienta: %s\n", buf); if( send(gniazdo2,buf,strlen(buf), 0) == -1 ) perror("send Error"); close (gniazdo2); close (gniazdo); exit(1); close (gniazdo2); close(gniazdo); return 0; Jako klienta aplikacji można użyć telnet. telnet localhost 7007 Literatura: 1. Wikipedia.org. 2. Strony podręcznika man. 3. W. Richard Stevens Programowanie zastosowań sieciowych w systemie Unix