+ All Categories
Home > Documents > Programarea în reţea (partea I)

Programarea în reţea (partea I)

Date post: 06-Feb-2017
Category:
Upload: vutuyen
View: 236 times
Download: 1 times
Share this document with a friend
48
Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/ Retele de calculatoare Programarea in retea I SabinCorneliu Buraga http://www.infoiasi.ro/~busaco
Transcript
Page 1: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Retele de calculatoareProgramarea in retea I

Sabin­Corneliu Buraga

http://www.infoiasi.ro/~busaco

Page 2: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

“If at first you don’t succeed,you must be a programmer.”/usr/games/fortune

Page 3: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Cuprins

• Modelul client/server• API pentru programarea in retea• Socket‐uri BSD• Modelul client/server TCP

Page 4: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Modelul client/server

Paradigme ale comunicarii in retea:

modelul client/server

apelul procedurilor la distanta (RPC)

comunicarea punct‐la‐punct (peer­to­peer – P2P)

Page 5: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Modelul client/server

• Proces server– Ofera servicii obtinute prin retea– Accepta (iterativ sau concurent) cereri de la un proces client, realizeaza un anumit serviciusi returneaza rezultatul

• Proces client– Initializeaza comunicarea cu serverul– Solicita un serviciu, apoi asteapta raspunsul serverului

Page 6: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Modelul client/serverClient

ProcessClient

ProcessProcessServer

TerminalServer

PrinterServer

FileServer

MemoryServer

Servicii nucleu (kernel)

ClientProcess

ClientProcess

ProcessServer

TerminalServer

PrinterServer

FileServer

MemoryServer

Kernel Kernel Kernel Kernel Kernel Kernel Kernel

O singura masina

Masini multiple (conectate la retea)

Page 7: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Modelul client/server• Moduri de interactiune (via canale de comunicatie):

orientat‐conexiune – se foloseste TCPneorientat‐conexiune – se utilizeaza UDP

• Implementare:iterativa – fiecare cerere e tratata pe rind, secventialconcurenta – cererile sint procesate concurent

Procese copil pentru fiecare cerere de procesatMultiplexarea conexiuniiTehnici combinate

Page 8: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

API retea• Necesitatea existentei unui API pentru realizarea de aplicatii in retea– Interfata generica pentru programare– Suport pentru comunicatii orientate‐conexiune siprin mesaje

– Compatibilitate cu serviciile I/O comune– Independenta de hardware si de sistem de operare– Suport pentru familii (suite) de protocoale multiple– Independenta in reprezentarea adreselor– Oferirea de servicii speciale pentru aplicatii

Page 9: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

API retea• TCP/IP nu include definirea unui API• Se pot utiliza mai multe API‐uri pentru programarea aplicatiilor Internet (TCP/IP)– Socket‐uri BSD (Berkeley System Distribution)– TLI (Transport Layer Interface) – AT&T, XTI– Winsock– MacTCP

• Functii oferite: specificare de puncte terminale locale si la distanta, initiere si acceptare de conexiuni, trimitere si receptare de date, terminare conexiune, tratare erori

Page 10: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Cuprins

• Interfata de programarea aplicatiilor (API) bazata pe socket‐uri BSD– Caracterizare– Creare– Primitive

Page 11: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket• Socket‐uri BSD (Berkeley System Distribution)• Facilitate generala, independenta de hardware, protocol si tipul de transmitere, pentru comunicarea intre proceseaflate pe masini diferite, in retea

• Suporta pentru familii multiple de protocoale– Protocolul domeniului UNIX pentru comunicatii(locale) intre masini UNIX (e.g., uucp) 

– Protocolul domeniului Internet folosind TCP/IP– Altele: XNS Xerox, ISO/OSI,…

• Independenta in reprezentarea adreselor

Page 12: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket• Abstractiune a unui punct terminal (end­point) la nivelul transport

• Utilizeaza interfata de programareI/O existenta(similar fisierelor, pipe‐urilor, FIFO‐urilor etc.)

• Poate fi asociat cu unul/mai multe procese, existind in cadrul unui domeniu de comunicatie

• Ofera un API pentru programarea in retea, avind implementari multiple

Page 13: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket

Similar unui descriptor de fisier

Diferente apar la creare si la diferite operatiunide control al socket‐urilor

Page 14: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket | primitive de baza

socket() creeaza un nou punct terminal al conexiuniibind() ataseaza o adresa locala la un socketlisten() permite unui socket sa accepte conexiuniaccept() blocheaza apelantul pina la sosireaunei cereri de conectare (utilizata de serverul TCP)

connect() tentativa (activa) de stabilire a conexiunii(folosita de clientul TCP)

send()/receive() trimitere/receptare de date via socketclose() elibereaza conexiunea (inchide un socket)shutdown() inchide directional un socket

Page 15: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket

• Alte apeluri– citire de dateread() / readv() / recvfrom() / recvmsg()

– trimitere de datewrite() / writev() / sendto() / sendmsg()

– multiplexare I/Oselect()

– administrarea conexiuniifnctl() / ioctl() / setsockopt() / getsockopt()getsockname() / getpeername()

Page 16: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|tabela de descriptori

Tabela de descriptori

0

1

2

3

4

Family: AF_INETService: SOCK_STREAMLocal IP: 193.231.30.197Local Port: 80Remote IP: 19.132.6.78Remote Port: 3726

Page 17: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|creare• Apelul de sistem (primitiva) socket()#include <sys/types.h>#include <sys/socket.h>

int socket (int domain, int type, int protocol)

Domeniul de comunicare: AF_UNIX, AF_INET,

AF_ROUTE

Protocolul utilizatpentru transmitere

(uzual: 0 pentru niv. transp.)

Modalitatea de realizare a comunicarii: SOCK_STREAM, SOCK_DGRAM, SOCK_RAW

Page 18: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|creare• Valoarea de retur– Succes: descriptorul de socket creat– Eroare: –1 

• Raportarea erorii se realizeaza via errno– EMFILE – ENFILE– EACCES– EPROTONOSUPPORT– ENOMEM– ENOBUFFERS– EINVAL

Constantedefinite in errno.h

Page 19: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri

• Domeniul & tipul unui socket si protocoalele folosite

AF_LOCAL ≡ AF_UNIX(din motive istorice)

AF_INET AF_INET6 AF_LOCAL AF_ROUTE SOCK_STREAM TCP TCP Da SOCK_DGRAM UDP UDP Da

SOCK_RAW IP IPv6 Da

Page 20: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri• Observatii

– Primitiva socket() aloca resursele necesareunui punct terminal de comunicare, dar nu stabileste modul de adresare

– Socket‐urile ofera un mod generic de adresare– Pentru TCP/IP trebuie specificate (adresa IP, port)– Alte suite de protocoale pot folosialte scheme de adresare

• Tipuri POSIX: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, u_char, u_short, u_int, u_long

Page 21: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri• Tipuri POSIX folosite de socket‐uri: 

– sa_family_t – familia de adrese – socklen_t – lungimea structurii de memorare – in_addr_t – adresa IP (v4) – in_port_t – numarul de port

• Specificarea adreselor genericestruct sockaddr {

uint8_t sa_len;sa_family_t sa_family; char sa_data[14];

};

Tipul de adresa

Valoarea adresei

Utiliz. de

nucleu

Page 22: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri

• Tipul sockaddr permite oricare tip de adresare• Exemplu: folosirea socket‐urilorpentru comunicarea dintre studenti– Tipul de adresa: AF_STUDENTS– Valori de adrese: Zaq⇔ 1, Moko⇔ 2, Tux ⇔ 3,…

– Initializarea structurii AF_STUDENTSpentru a indica un anumit student: struct sockaddr un_stud;un_stud.sa_family = AF_STUDENTS;un_stud.sa_data[0] = 3;

Tux

Page 23: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri• Pentru AF_INET vom avea nevoie de 16 biti – numarul de port si de 32 biti – adresa IPv4

• Se foloseste o structura speciala: sockaddr_instruct sockaddr_in {

uint8_t sin_len;sa_family_t sin_family;in_port_t sin_port;struct in_addr sin_addr; char sin_zero[8];

};struct in_addr {

in_addr_t s_addr;};

Page 24: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri

sin_lensa_lensa_family

sa_data

AF_INETsin_port

sin_addr

sin_zero

sockaddr sockaddr_in

Page 25: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri• Toate valorile stocate in sockaddr_in vor respectaordinea de codificare a retelei (network byte order)sin_port un numar de port TCP/IPsin_addr o adresa IP

• ‘h’ : host byte order  ‘n’ : network byte order• ‘s’ : short (16 biti) ‘l’ : long (32 biti)

uint16_t htons(uint16_t);uint16_t ntohs(uint_16_t);

uint32_t htonl(uint32_t);uint32_t ntohl(uint32_t);

Page 26: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri• Pentru IPv6, se foloseste sockaddr_in6struct sockaddr_in {u_int16_t sin6_family; /* AF_INET6 */u_int16_t sin6_port;u_int32_t sin6_flowinfo;u_int32_t sin6_scope_id;struct in6_addr sin6_addr; };

struct in6_addr {unsigned char s6_addr[16];

};

Page 27: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|asignarea unei adrese• Asignarea unei adrese la un socket existent se realizeaza cu bind()

int bind ( int sockfd, const struct sockaddr *myaddr,int addrlen );

• Se returneaza:  0 succes, –1 eroare variabila errno contine eroarea efectiva: EBADF, ENOTSOCK, EADDRINUSE, EINVAL, EACCESS

const!

Page 28: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|asignarea unei adrese• Exemplu:

#define PORT 7000int sd, eroare;struct sockaddr_in adresa;

sd = socket (AF_INET, SOCK_STREAM, 0); /* TCP */adresa.sin_family = AF_INET; /* umplerea structurii */adresa.sin_port = htons (PORT); /* portul */adresa.sin_addr = htonl (adresaIP); /* adresa IP */

eroare = bind (sd, (sockaddr *) &adresa, sizeof (adresa));

Page 29: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|asignarea unei adrese• Utilizari ale lui bind()

– Serverul doreste sa ataseze un socket la un port pre‐stabilit (pentru a oferi servicii via acel port)

– Clientul vrea sa ataseze un socket la un port specificat– Clientul cere sistemului de operare sa asignezeorice port disponibil

• In mod normal, clientul nu necesita atasareala un port specificat

• Alegerea oricarui port liber: adresa.port = htons (0);

Page 30: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|asignarea unei adrese

• Alegerea adresei IP la bind()– Daca gazda are asignate mai multe adrese IP?– Cum se rezolva independenta de platforma?

• Pentru a atasa un socket la adresa IP locala, se va utilizain locul unei adrese IP constanta INADDR_ANY

Page 31: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|asignarea unei adrese

• Conversia adreselor IP:int inet_aton ( void *, struct in_addr *);ASCII “x.x.x.x” ⇒ reprezentare interna pe 32 biti

char *inet_ntoa ( struct in_addr );reprezentare 32 biti (network byte order) ⇒ ASCII “x.x.x.x”

vezi si functia inet_addr()

Page 32: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|asignarea unei adrese

• Observatii:– Pentru IPv6 in locul constantei INADDR_ANYse va folosi – vezi antetul netinet/in.h:serv.sin6.addr = in6addr_any;

– Functiile de conversie pentru IPv6 sunt:inet_pton()inet_ntop()

Page 33: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|listen()• Stabilirea modului pasiv de interactiune

– Adresa intotdeauna este cunoscuta– Nucleul sistemului va trebui sa accepte cereride conectare directionate la adresa la care este atasat socket‐ul3­way handshake

– Conexiunile multiple receptionatevor fi plasate intr‐o coada de asteptare

– Se returneaza 0 = succes, –1 = eroare

int listen ( int sockfd, int backlog );

Socket TCP atasat unei adrese

Numarul de conex. din coada de astept.

Page 34: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|listen()

• Remarci:– Alegerea valorii backlog depindede aplicatie – in mod uzual 5

– Serverele HTTP ar trebui sa specificeo valoare backlog cit mai mare (din cauza incarcarii cu cereri multiple)

Page 35: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|accept()• Asteptarea conexiunilor din partea clientilor

– Cind aplicatia este pregatita pentru a trata o noua conexiune, va trebui sa interogam sistemul asupra unei alte conexiuni cu un client

– Se returneaza descriptorul de socket corespunzator punctului terminal al clientului sau –1 = eroare

int accept( int sockfd,struct sockaddr* cliaddr, socklen_t *addrlen );

Socket TCP (mod pasiv)

• trebuie initial sa fie egal cu lungimea structurii cliaddr• se va returna numarul de bytes folositi in cliaddr

Page 36: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|connect()• Incercarea de a stabili o conexiune cu serverul

– Stabilirea unui punct terminal (al serverului)– Nu necesita atasarea cu bind(), sistemulde operare va asigna o adresa locala (IP, port)

– Se incearca stabilirea unei conexiuni3­way handshake

int connect( int sockfd,const struct sockaddr *server,socklen_t addrlen );

Socket TCP

Contine adresa serverului (IP, port)

Page 37: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Socket‐uri|connect()• Returneaza:

– Valoarea 0 = succes– Valoarea –1 = eroare

• EISCONN• ETIMEDOUT• ECONNREFUSED• ENETUNREACH• EADDRINUSE• EINPROGRESS• EADDRNOTAVAIL• EAFNOSUPPORT

Page 38: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

I/O TCP|read()• Apelul este blocant in mod normal, read() returneaza doar cind exista date disponibile

• Citirea de la un socket TCP poate returnamai putini octeti decit numarul maxim dorit

• Trebuie sa fim pregatiti sa citim cite 1 byte la un moment dat!

• Daca partenerul a inchis conexiunea si nu mai sunt date de primit, se returneaza 0 (EOF)

• Erori: EINTR – un semnal a intrerupt citirea, EIO – eroare I/O, EWOULDBLOCK – socket‐ul nu are date intr‐o citire neblocantaint read ( int sockfd, void *buf, int max );

Page 39: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

I/O TCP|write()• Apelul este blocant in mod normal• Pentru un socket neblocant, write() poate scrie mai putin de num octeti

• Erori: – EPIPE – scriere la un socket neconectat– EWOULDBLOCK – nu se pot accepta date fara blocare, insa operatiunea este setata ca fiind neblocanta

int write ( int sockfd, void *buf, int num );

Page 40: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

I/O TCP|exemplu#define MAXBUF 127 /* lungime buffer citire */char *cerere = “da-mi ceva”;char buf[MAXBUF]; /* buffer pentru raspuns */char *pbuf = buf; /* pointer la buffer */int n, lung = MAXBUF;

/* nr. bytes cititi, nr. bytes liberi in buffer */

/* trimitem cererea */write (sd, cerere, strlen (cerere));

/* asteaptam raspunsul */while ((n = read (sd, pbuf, lung)) > 0) {pbuf += n;lung -= n;

} Comunicarea dintre client si server

Page 41: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Inchiderea conexiunii|close()

• Terminarea “gratioasa” a conexiunii• Dealocarea memoriei alocate socket‐ului

– 3­way handshake pentru inchiderea conexiunii– Pentru procese care partajeaza acelasi socket, se decrementeaza numarul de referinte la acel socket; cind ajunge la 0, socket‐ul este dealocat

• Probleme– Serverul nu poate termina conexiunea, nu stie daca si cind clientul nu va mai trimite si alte cereri

– Clientul nu poate sti daca datele au ajuns la server

int close ( int sockfd );

Page 42: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Inchiderea conexiunii|shutdown()• Inchiderea unidirectionala

– Cind un client termina de trimis cererile, poate apela shutdown() pentru a specifica faptul ca nu va mai trimite date pe socket, fara a dealoca socket‐ul

– Serverul va primi EOF si, dupa expedierea catre client a ultimului raspuns, va putea inchide conexiunea

int shutdown ( int sockfd, int dir );

• 0 nu se accepta operatii de citire (SHUT_RD)• 1 nu se accepta operatii de scriere (SHUT_WR)• 2 nu se accepta operatii I/O

inchidere in ambele sensuri (SHUT_RDWR)

Page 43: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Metaphor for Good RelationshipsCopyright Dr. Laura’s Network Programming Corp.

To succeed in relationships…– you need to establish your own identity.– you need to be open & accepting.– you need to establish contacts.– you need to take things as they come, not as you expect them.

– you need to handle problems as they arise.

Page 44: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Client/server TCP|server• Modelul unui server TCP iterativ

– Creare socket pentru tratarea conexiunilor cu clientii: socket()– Pregatirea structurilor de date (sockaddr_in) – Atasarea socket‐ului la adresa locala (port): bind()– Pregatirea socket‐ului pentru ascultarea portuluiin vederea stabilirii conexiunii cu clientii: listen()

– Asteptarea realizarii unei conexiuni cu un anumit client (deschidere pasiva): accept()

– Procesarea cererilor clientului, folosindu‐se socket‐ul returnatde accept(): succesiune de read()/write()

– Inchiderea (directionata) a conexiunii cu clientul: close(), shutdown()

Page 45: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Client/server TCP|client

• Modelul unui client TCP iterativ– Creare socket pentru conectarea la server: socket()– Pregatirea structurilor de date (sockaddr_in) – Atasarea socket‐ului: bind() – optional– Conectarea la server (deschidere activa): connect()– Solicitarea de servicii si receptionarea rezultatelor trimise de server: succesiune de write()/read()

– Inchiderea (directionata) a conexiunii cu serverul: close(), shutdown()

Page 46: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Page 47: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Rezumat

• Modelul client/server• API pentru programarea in retea• Socket‐uri BSD

– Caracterizare– Creare– Primitive

• Modelul client/server TCP

Page 48: Programarea în reţea (partea I)

Dr. Sabin-Corneliu Buraga – www.infoiasi.ro/~busaco/

Intrebari?


Recommended