Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład...

44
Programowanie aplikacji równoleglych i rozproszonych Wyklad 4 Dr in ˙ z. Tomasz Olas [email protected] Instytut Informatyki Teoretycznej i Stosowanej Politechnika Cz˛ estochowska Wyklad 4 – p. 1/44

Transcript of Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład...

Page 1: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Programowanie aplikacjirównoległych i rozproszonych

Wykład 4Dr inz. Tomasz Olas

[email protected]

Instytut Informatyki Teoretycznej i Stosowanej

Politechnika Czestochowska

Wykład 4 – p. 1/44

Page 2: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Gniazda - Wstep

Podstawa mechanizmu wejscia-wyjscia dla sieci w systemieUnix jest abstrakcyjny mechanizm znany jako gniazda (ang.socket).

Gniazdo nalezy traktowac jako jako uogólnienie mechanizmudostepu do plików udostepniajace jeden z konców łaczakomunikacyjnego.

Kazdy z komunikujacych sie ze soba procesów tworzy poswojej stronie jedno gniazdo.

Główna róznica pomiedzy deskryptorami plików i gniazdamipolega na tym, ze system operacyjny wiaze deskryptorz okreslonym plikiem lub urzadzeniem, natomiast gniazdamozna tworzyc bez wiazania ich z okreslonym adresemodbiorcy.

Gniazdo jest opisywane za pomoca kombinacji trzechatrybutów: domeny adresowej, sposobu komunikacjii protokołu sieciowego.

Wykład 4 – p. 2/44

Page 3: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Domena adresowa

Domena adresowa okresla domene w której bedzierealizowana komunikacja:

PF_LOCAL (PF_UNIX) - komunikacja w obrebie jednejmaszyny,PF_INET - Internet, czyli uzywamy protokołów z rodzinyTCP/IP,PF_IPX - protokoły IPX/SPX (Novell),PF_PACKET- niskopoziomowy interfejs do odbieraniapakietów w tzw. surowej (ang. raw) postaci.

Zamiennie uzywa sie notacji PF_xxx (PF - Protocol Family)oraz AF_xxx (AF - Address Family).

Wykład 4 – p. 3/44

Page 4: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Sposób komunikacji

Gniazda typu SOCK_STREAM- komunikacja w modelupołaczeniowym (zwykle zwiazane z protokołem TCP warstwytransportowej)

Gniazda typu SOCK_DGRAM- komunikacja w modelubezpołaczeniowym korzystajaca z tzw. datagramów (zwyklezwiazane z protokołem UDP warstwy transportowej)

Gniazda typu SOCK_RAW- komunikacja na niskim poziomie -dostep do surowych pakietów na poziomie warstwy sieciowejTCP/IP.

Wykład 4 – p. 4/44

Page 5: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Funkcja socketpair

Do tworzenia gniazdek w domenie unixowej moze zostacwykorzystana funkcja socketpair :#include <sys/types.h>

#include <sys/socket.h>

int socketpair(int family, int type, int protocol, int sock vec[2]);

Funkcja zwraca deskryptor gniazda.

family - oznacza domene komunikacyjna (czyli rodzine protokołów adresów) wjakiej bedzie funkcjonowac nowe gniazdo. W systemie Linux jedyna obsługiwanadomena jest PF_UNIX.

type - okresla rodzaj gniazda,

protocol - protokół z jakiego gniazdo korzysta,

sockver - gdy nie wystapi bład zostana do tej zmiennej zapisana paradeskryptorów gniazd w domenie Unixa. Otrzymuje sie w ten sposób łaczestrumieniowe z mozliwoscia dwustronnej komunikacji.

Wykład 4 – p. 5/44

Page 6: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Zamkniecie gniazda

Funkcje close słuzy do zamykania gniazda i konczeniapołaczenia:int close(int fd);

fd - deskryptor gniazda,wynik:

0 - w przypadku sukcesu,-1 - jesli wystapił bład.

Przy wywoływaniu funkcji close zmniejszany jest licznikodwołan do deskryptora.

Gdy proces sie konczy, system operacyjny zamyka wszystkiegniazda, które były wówczas otwarte.

Wykład 4 – p. 6/44

Page 7: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Przesyłanie danych

Przesyłanie danych poprzez gniazda moze odbywac sie zwykorzystaniem pieciu róznych funkcji systemowych:send/write , sendto/recvfrom , sendmsg/recvmsg ,write/read , writev/readv .Procedury send/recv , sendto/redvfrom orazsendmsg/recvmsg wymagaja aby gniazdo było przyłaczone,gdyz nie umozliwiaja podania adresu odbiorcy.

wiele dodatkowe adres informacje

buforów znaczniki partnera kontrolne

read/write

readv/writev +

send/recv +

sendto/recvfrom + +

sendmsg/recvmsg + + + +

Wykład 4 – p. 7/44

Page 8: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

read/write

ssize_t read(int fd, void * buf, size_t count)

ssize_t write(int fd, const void * buf, size_t count)

fd - deskryptor,

buff - adres danych do odczytania/zapisania,

length - rozmiar danych do odczytania/zapisania.

wynik:liczba odczytanych/zapisanych bajtów - w przypadkusukcesu,-1 - w przypadku błedu.

Wykład 4 – p. 8/44

Page 9: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

socketpair - przykład (1)

#include <sys/types.h>

#include <sys/socket.h>

#include <unistd.h>

#include <iostream>

const int SIZE = 40;

int main()

{

int sockets[2];

socketpair(PF_UNIX, SOCK_STREAM, 0, sockets);

int pid = fork();

if (pid == 0) { // proces potomny

close(sockets[1]);

char buf[SIZE];

sprintf(buf, "proces potomny: %d", getpid());

write(sockets[0], buf, sizeof(buf) + 1);

read(sockets[0], buf, SIZE);

close(sockets[0]);

std::cout << "#1: " << getpid() << "\n#1: " << buf << std::endl ;

}

Wykład 4 – p. 9/44

Page 10: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

socketpair - przykład (2)

...

else

{ // proces macierzysty

close(sockets[0]);

char buf[SIZE];

read(sockets[1], buf, SIZE);

std::cout << "#0: " << getpid() << "\n#0: " << buf << std::endl ;

sprintf(buf, "proces macierzysty: %d", getpid());

write(sockets[1], buf, sizeof(buf) + 1);

close(sockets[1]);

}

return 0;

}

Wykład 4 – p. 10/44

Page 11: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

socketpair - przykład (3)

Przykładowy rezultat działania programu:#0: 1458

#0: proces potomny: 1459

#1: 1459

#1: proces macierzysty: 1458

Wykład 4 – p. 11/44

Page 12: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Komunikacja bezpołaczeniowa

Wykład 4 – p. 12/44

Page 13: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Tworzenie gniazd

Uzytkownik identyfikuje gniazda za pomoca deskryptorów(wykorzystywanych przy kazdorazowym odwoływaniu sie dogniazda)

Funkcja socket tworzy nowe gniazdo i zwraca jegodeskryptor:int socket (int family, int type, int protocol);

family - oznacza domene komunikacyjna (czyli rodzine protokołów adresów) wjakiej bedzie funkcjonowac nowe gniazdo, np:

PF_INET - domena internetowa - siec TCP/IP,PF_UNIX - domena uniksowa - komunikacja lokalna (system plików systemuUnix),PF_APPLETALK- siec firmy Apple Computer Incorporated,

type - okresla rodzaj gniazda,

protocol - protokół z jakiego gniazdo korzysta (w przypadku 0 bedzie todomyslny protokół dla danego rodzaju gniazda).

Wykład 4 – p. 13/44

Page 14: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Okreslanie adresu lokalnego

Poczatkowo nowo utworzone gniazdo nie jest zwiazane zzadnym adresem lokalnym ani odległym.

Po utworzeniu gniazda serwer wiaze z nim adres lokalny zapomoca funkcji systemowej bind :int bind(int fd, struct sockaddr * my_addr, int addrlen)

fd - deskryptor gniazda,my_addr - wskaznik na strukture adresów odpowiednia dlarodziny protokołów, do której nalezy gniazdo,addrlen - rozmiar tej struktury.

Wykład 4 – p. 14/44

Page 15: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Struktura sockaddr

Dla domeny uniksowej:struct sockaddr_un

{

short sun_family; / * AF_UNIX * /

char sun_data; / * scie zka * /

};

Dla domeny internetowej:struct sockaddr_in

{

short sin_family; / * AF_INET * /

u_short sin_port; / * 16-bitowy numer portu * /

struct in_addr sin_addr; / * 32-bitowy internetowy * /

/ * adres hosta * /

char sin_zero[8]; / * zarezerwowane * /

};

Wykład 4 – p. 15/44

Page 16: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Funkcje send i sendto

ssize_t send(int s, const void * buf, size_t len, int flags);

ssize_t sendto(int s, const void * buf, size_t len, int flags,

const struct sockaddr * to, socklen_t tolen);

ssize_t recvfrom(int s, void * buf, size_t len, int flags,

struct sockaddr * from, socklen_t * fromlen);

s - deskryptor gniazda, przez które wysyłamy dane,

buf - wskaznik do bufora, który chcemy wysłac,

len - liczba bajtów bufora do wysłania,

flags - dodatkowe flagi (np. codeMSG_DONTWAIT -Przełacza funkcje w tryb nieblokujacy),

to - wskaznik do struktury zawierajacej adres odbiorcy,

addrlen - rozmiar struktury zawierajacej adres.

wynik:liczba odczytanych/zapisanych bajtów - w przypadkusukcesu,-1 - w przypadku błedu. Wykład 4 – p. 16/44

Page 17: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Funkcje recv i recvfrom

ssize_t recv(int s, void * buf, size_t len, int flags);

ssize_t recvfrom(int s, void * buf, size_t len, int flags,

struct sockaddr * from, socklen_t * fromlen);

s - deskryptor gniazda, przez które odbieramy dane,

buf - adres (wskaznik) bufora, który bedzie zawierał dane poich odebraniu,

len - rozmiar bufora (maksymalna liczba bajtów, która moznajednorazowo odebrac),

flags - dodatkowe flagi,

to - wwskaznik do struktury, przez która zwrócony zostanieadres nadawcy,

addrlen - rozmiar struktury zawierajacej adres.

Wykład 4 – p. 17/44

Page 18: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Przykład (I)

const char name[] = "my_socket";

int main()

{

int orginal_socket = socket(AF_UNIX, SOCK_DGRAM, 0);

unlink(name);

sockaddr_un server_address;

server_address.sun_family = AF_UNIX;

strcpy(server_address.sun_path, name);

bind(orginal_socket, (sockaddr * )&server_address,

sizeof(server_address.sun_family) + sizeof(server_add ress.sun_path));

char buf[255];

while (true) {

socklen_t client_length;

recvfrom(orginal_socket, buf, sizeof(buf), 0,

(sockaddr * )&server_address, &client_length);

std::cout << buf << std::endl;

}

close(orginal_socket); return 0;

} Wykład 4 – p. 18/44

Page 19: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Przykład (II)

const char name[] = "my_socket";

int main(int argc, char ** argv)

{

int orginal_socket = socket(AF_UNIX, SOCK_DGRAM, 0);

sockaddr_un server_address;

server_address.sun_family = AF_UNIX;

strcpy(server_address.sun_path, name);

bind(orginal_socket, (sockaddr * )&server_address,

sizeof(server_address.sun_family) + sizeof(server_add ress.sun_path));

sendto(orginal_socket, argv[1], sizeof(argv[1]), 0,

(sockaddr * )&server_address, sizeof(sockaddr));

close(orginal_socket);

return 0;

}

Wykład 4 – p. 19/44

Page 20: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Model klient serwer

Termin serwer odnosi sie do kazdego programu, który oferujeusługe dostepna poprzez siec. Serwer przyjmuje przez sieczamówienia, wykonuje usługe i zwraca wyniki zamawiajacemu.

Klientem staje sie program, który wysyła zamówienie doserwera i czeka na odpowiedz.

W przypadku modelu klient serwer kazde połaczenie sieciowejest tworzone przez klienta wysyłajacego zadania do staleoczekujacego na nie serwera.

Gniazda uzywane przez procesy klienckie nazywane sagniazdami aktywnymi (one inicjuja połaczenie), natomiastgnizda wykorzystywane w serwerach nazywane saanalogicznie gniazdami pasywnymi.

Wykład 4 – p. 20/44

Page 21: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Komunikacja połaczeniowa

Wykład 4 – p. 21/44

Page 22: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Serwer - przyjmowanie połacze n (I)

Serwer uzywa funkcji socket , bind i listen do utworzeniagniazda. Wywołanie bind wiaze gniazdo z powszechnieznanym portem protokołu, ale nie powoduje podłaczeniagniazda do zadnego odległego odbiorcy. Zamiast odległegoodbiorcy podaje sie adres uogólniajacy (ang. wildcard), bygniazdo mogło przyjmowac połaczenia od dowolnych klientów.

Po utworzeniu gniazda serwer czeka na połaczenia. W tymcelu wywołuje procedure systemowa accept .

Wykład 4 – p. 22/44

Page 23: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Serwer - przyjmowanie połacze n (II)

Gdy nadchodzi zadanie, system wypełnia strukture addradresem klienta, który je zgłosił.

Nastepnie system tworzy nowe gniazdo, które jest połaczone zklientem i dostarcza wywołujacemu programowi deskryptortego gniazda.

Pierwotne gniazdo nadal nie jest połaczone z zadnymkonkretnym odległym klientem i pozostaje w dalszym ciaguotwarte. Dzieki temu serwer nadal moze czekac na zadanianadchodzace za posrednictwem tego gniazda.

Wywołanie accept konczy sie po nadejsciu zadaniapołaczenia.

Serwer moze obsługiwac nadchodzace zadania po kolei, badztez współbieznie.

Wykład 4 – p. 23/44

Page 24: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

listen

Funkcja listen ustala maksymalna długosc kolejki klientówoczekujacych na połaczenie.#include <sys/types.h>

#include <sys/socket.h>

int listen(int fd, int backlog);

fd - deskryptor gniazda,backlog - maksymalna liczba zgłoszen połaczenia zserwerem.wynik:

0 - w przypadku sukcesu,wartosc ujemna - jesli wystapił bład.

W przypadku domeny uniksowej gniazdo musi bycstrumieniowe i miec dowiazana nazwe.

W przypadku domeny internetowej, jesli gniazdo nie manazwy, to funkcja listen automatycznie je dowiaze.

Wykład 4 – p. 24/44

Page 25: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

accept

Funkcja accept słuzy do oczekiwania na połaczenie - procesjest blokowany az do momentu nawiazania połaczenia przezklienta. W momencie nawiazania połaczenia funkcja acceptzwraca nowy deskryptor gniazda, który nastepnie jest uzywanydo komunikacji z klientem:#include <sys/types.h>

#include <sys/socket.h>

int accept(int fd, struct sockaddr * upeer_sockaddr,

int * upeer_addrlen);

fd - deskryptor gniazda,

upeer_sockaddr - wskaznik na nazwe gniazda klienta (jako dodatkowy wynik)

upeer_addrlen - rozmiar nazwy upeer_sockaddr (jako dodatkowy wynik)

wynik:0 - w przypadku sukcesu,-1 - jesli wystapił bład.

Wykład 4 – p. 25/44

Page 26: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Serwer - przykład (I)

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <unistd.h>

#include <iostream>

const char name[] = "my_socket";

int main()

{

int orginal_socket = socket(AF_UNIX, SOCK_STREAM, 0);

sockaddr_un server_address;

server_address.sun_family = AF_UNIX;

strcpy(server_address.sun_path, name);

unlink(name);

bind(orginal_socket, (sockaddr * )&server_address,

sizeof(server_address.sun_family) +

sizeof(server_address.sun_path));

Wykład 4 – p. 26/44

Page 27: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Server - przykład (II)

listen(orginal_socket, 1);

sockaddr_un client_address;

socklen_t client_length = sizeof(client_address);

int new_socket = accept(orginal_socket, (sockaddr * )&client_address,

&client_length);

char buf[255];

read(new_socket, buf, sizeof(buf));

std::cout << buf << std::endl;

close(new_socket);

close(orginal_socket);

unlink(name);

return 0;

}

Wykład 4 – p. 27/44

Page 28: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Łaczenie gniazda z adresem odbiorcy

Bezposrednio po utworzeniu gniazda znajduje sie ono w stanieniepołaczonym , co oznacza, ze nie jest ono zwiazane z zadnymadresatem.

Procedura systemowa connect trwale łaczy gniazdo zadresem odbiorcy, zmieniajac jednoczesnie stan gniazda napołaczony .

W przypadku komunikacji w trybie połaczeniowym klient przedrozpoczeciem przesyłania danych za posrednictwem gniazdamusi wywołac procedure connect w celu uzyskaniapołaczenia.

Gniazda uzywane w trybie bezpołaczeniowym nie wymagajapodłaczania przed uzyciem, ale dzieki podłaczeniu moznawysyłac dane do gniazda, nie okreslajac za kazdym razemadresu odbiorcy.

Wykład 4 – p. 28/44

Page 29: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

connect

Funkcja connect :int connect(int fd, struct sockaddr * uservaddr, int addrlen);

fd - deskryptor gniazda,uservaddr - struktura okreslajaca adres, z którym nalezyzwiazac wskazane gniazdo,addrlen - rozmiar struktury uservaddr .wynik:

0 - w przypadku sukcesu,wartosc ujemna - w przypadku błedu, np:· EBADF- fd jest nieprawidłowym deskryptorem,· ENOTSOCK- fd nie jest deskryptorem gniazda,· EISCONN- jest juz zrealizowane polaczenie.

Wykład 4 – p. 29/44

Page 30: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Klient - przykład

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <unistd.h>

#include <iostream>

const char name[] = "my_socket";

int main()

{

int orginal_socket = socket(AF_UNIX, SOCK_STREAM, 0);

sockaddr_un server_address;

server_address.sun_family = AF_UNIX;

strcpy(server_address.sun_path, name);

connect(orginal_socket, (sockaddr * )&server_address,

sizeof(server_address.sun_family) + sizeof(server_add ress.sun_path));

char buf[] = "hello";

write(orginal_socket, buf, sizeof(buf));

close(orginal_socket);

return 0;

} Wykład 4 – p. 30/44

Page 31: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Adres sieciowy

Kazdy host w sieci ma przynajmniej dwa tylko własciwe sobieadresy:

48-bitowy adres ethernetowy (przypisywany ethernetowejkarcie sieciowej przez producenta),32-bitowy adres internetowy (tzw. numer IP). W interakcji zuzytkownikiem jest on podzielony na cztery 8-bitowe liczbydziesietne separowane kropkami. Kazda z tych liczb mozesie zawierac w przedziale od 0 do 255, choc wartoscibrzegowe sa uzywane jako wartosci specjalnegoprzeznaczenia.

Wykład 4 – p. 31/44

Page 32: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Numer portu

Numer portu jest liczba 16-bitowa bez znaku.

Jednoznacznie identyfikuje połaczenie sieciowe w ramachjednego adresu IP.

Para (adres IP, numer portu) jednoznacznie okresla komputerw sieci, jak równiez konkretny proces działajacy na tymkomputerze.

Wykład 4 – p. 32/44

Page 33: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Funkcja gethostbyname (I)

W przypadku domeny internetowej procesy muszadysponowac swoimi adresami hostów i numerami portów, abymogły ze soba nawiazac kontakt.

Funkcja gethostbyname zwraca pełne informacje o hoscie,którego nazwe podano w argumentach:#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

hostent * gethostbyname(const char * name);

name - wskaznik na napis zawierajacy nazwe hosta.

Jesli nazwa hosta zostanie znaleziona funkcja zwróci wskaznik na strukturehostent , w przeciwnym wypadku zwróci NULL.

Wykład 4 – p. 33/44

Page 34: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Funkcja gethostbyname (II)

struct hostent

{

char * h_name;

char ** h_aliases;

int h_addrtype;

int h_length;

char ** h_addr_list;

#define h_addr h_addr_list[0]

};

h_name - oficjalna nazwa hosta,

h_aliases - lista aliasów,

h_addrtype - typ adresu hosta,

h_length - długosc adresu,

h_addr_list - lista adresów z serwera nazw.

Wykład 4 – p. 34/44

Page 35: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Zmiana kolejno sci bajtów

Poszczególne typy komputerów róznia sie sposobemprzechowywania liczb, a protokoły TCP/IP okreslaja niezaleznyod maszyny standard porzadku bajtów liczb.

System Unix BSD oferuje cztery procedury bibliotecznesłuzace do konwersji miedzy porzadkiem bajtów na danymkomputerze oraz sieciowym porzadkiem bajtów(<netinet/in.h> ):

Do zamiany liczby z reprezentacji sieciowej do reprezentacji lokalnej (network tohost) słuza funkcje:

uint16_t ntohs(uint16_t netshort);

uint32_t ntohl(uint32_t netlong);

Do konwersji liczb z porzadku danego komputera na porzadek sieciowy (host tonetwork) słuza funkcje:

uint16_t htons(uint16_t hostshort);

uint32_t htonl(uint32_t hostlong);

Wykład 4 – p. 35/44

Page 36: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

gethostbyname - przykład (I)

hostent * host;

std::string hostName;

std::cout << "Podaj nazwe hosta: " << std::flush;

std::getline(std::cin, hostName);

host = gethostbyname(hostName.c_str());

if (host != NULL)

{

std::cout << "Oficialna nazwa: " << host->h_name << std::en dl

<< "Aliasy: " << std::endl;

while ( * host->h_aliases)

{

std::cout << " " << * host->h_aliases << std::endl;

++host->h_aliases;

}

std::cout << "Typ adresu: " << host->h_addrtype << std::end l

<< "Dlugosc adresu: " << host->h_length << std::endl

<< "Lista adresów: " << std::endl;

Wykład 4 – p. 36/44

Page 37: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

gethostbyname - przykład (II)

while ( * host->h_addr_list) {

in_addr in;

memcpy(&in.s_addr, * host->h_addr_list, sizeof(in.s_addr));

std::cout << "[" << host->h_addr_list << "] = "

<< inet_ntoa(in) << std::endl;

++host->h_addr_list;

}

}

}

Przykładowy wynik działania programu:Podaj nazwe hosta: icis

Oficialna nazwa: icis.pcz.pl

Aliasy:

Typ adresu: 2

Dlugosc adresu: 4

Lista adresów:

[0x6031d0] = 212.87.224.6

Wykład 4 – p. 37/44

Page 38: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Domena internetowa - serwer (I)

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <iostream>

#include "local.h"

int main()

{

int orginal_socket = socket(AF_INET, SOCK_STREAM, 0);

if (orginal_socket < 0)

{

perror("blad generowania");

exit(1);

}

sockaddr_in server_address;

memset(&server_address, 0, sizeof(sockaddr_in));

server_address.sin_family = AF_INET;

server_address.sin_addr.s_addr = htonl(INADDR_ANY);

server_address.sin_port = htons(PORT);Wykład 4 – p. 38/44

Page 39: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Domena internetowa - serwer (II)

if (bind(orginal_socket, (sockaddr * )&server_address,

sizeof(server_address)) < 0) {

perror("blad dowiazania");

exit(2);

}

if (listen(orginal_socket, 5) < 0) {

perror("blad nasluchu");

exit(3);

}

do {

sockaddr_in client_address;

socklen_t client_len = sizeof(client_address);

int new_socket = accept(orginal_socket,

(sockaddr * )&client_address,

&client_len);

if (new_socket < 0) {

perror("blad akceptowania");

exit(4);

}

Wykład 4 – p. 39/44

Page 40: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Domena internetowa - serwer (III)

if (fork() == 0) {

int len;

const int BUFSIZE = 255;

char buf[BUFSIZE];

while ((len = read(new_socket, buf, BUFSIZE)) > 0)

{

for (int i = 0; i < len; i++)

buf[i] = toupper(buf[i]);

write(new_socket, buf, len);

if (buf[0] == ’.’)

break;

}

close(new_socket);

exit(0);

}

else

close(new_socket);

}

while (true);

}

Wykład 4 – p. 40/44

Page 41: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Domena internetowa - klient (I)

int main(int argc, char ** argv)

{

hostent * host = gethostbyname(argv[1]);

sockaddr_in server_address;

memset(&server_address, 0, sizeof(server_address));

server_address.sin_family = AF_INET;

memcpy(&server_address.sin_addr, host->h_addr, host-> h_length);

server_address.sin_port = htons(PORT);

int orginal_socket = socket(AF_INET, SOCK_STREAM, 0);

if (orginal_socket < 0) {

perror("blad generowania");

exit(3);

}

if (connect(orginal_socket, (sockaddr * )&server_address,

sizeof(server_address)) < 0) {

perror("blad polaczenia");

exit(4);

}Wykład 4 – p. 41/44

Page 42: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Domena internetowa - klient (II)

char buf[255];

std::string line;

do

{

std::cout << "> " << std::flush;

getline(std::cin, line);

write(orginal_socket, line.c_str(), line.size()+1);

read(orginal_socket, buf, 255);

std::cout << buf << std::endl;

}

while (line[0] != ’.’);

close(orginal_socket);

exit(0);

}

Wykład 4 – p. 42/44

Page 43: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Lokalne i odległe adresy gniazd

Do ustalenia adresu odbiorcy, z którym jest połaczone danegniazdo słuzy funkcja:#include <sys/socket.h>

int getpeername(int s, struct sockaddr * name, socklen_t * namelen);

Procedura getsockname dostarcza lokalnego adresuzwiazanego z danym gniazdem:#include <sys/socket.h>

int getsockname(int s, struct sockaddr * name, socklen_t * namelen);

Wykład 4 – p. 43/44

Page 44: Programowanie aplikacji równoległych i rozproszonych …icis.pcz.pl/~olas/parr/wyklad4.pdfWykład 4 – p. 24/44 accept Funkcja acceptsłuzy do oczekiwania na poła˛czenie - proces˙

Obsługa wielu klientów

Funkcje accept , send , recv , sendto , recfrom sablokujace.

Aby serwer mógł obsługiwac wielu klientów nalezy:utworzyc dla kazdego klienta oddzielny proces,obsługiwac poszczególnych klientów przy uzyciudodatkowych watków,wykorzystac funkcje select .

Wykład 4 – p. 44/44