STAW 08/12: Programare Web. Suita de tehnologii HTML5
Computer Networks. Internet programming basics
1. Retele de calculatoare
Retele de calculatoare
Programarea in retea – I
Sabin-Corneliu Buraga
busaco@infoiasi.ro
http://www.infoiasi.ro/~busaco
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [1]
2. Retele de calculatoare
Cuprins
• Modelul client/server
• API pentru programarea in retea
• Socket-uri BSD
• Modelul client/server TCP
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [2]
3. Retele de calculatoare
Modelul client/server
• Paradigme ale comunicarii in retea:
– Modelul client/server
– Apelul procedurilor la distanta (RPC)
– Comunicarea punct-la-punct (peer-to-peer – P2P)
• Proces server
– Ofera servicii obtinute prin retea
– Accepta (iterativ sau concurent) cereri de la
un proces client, realizeaza un anumit serviciu
si returneaza rezultatul
• Proces client
– Initializeaza comunicarea cu serverul
– Solicita un serviciu,
apoi asteapta raspunsul serverului
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [3]
4. Retele de calculatoare
Modelul client/server
Client Client Process Terminal Printer File Memory
Process Process Server Server Server Server Server
Servicii nucleu (kernel)
O singura masina
Client Client Process Terminal Printer File Memory
Process Process Server Server Server Server Server
Kernel Kernel Kernel Kernel Kernel Kernel Kernel
Masini multiple (conectate la retea)
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [4]
5. Retele de calculatoare
Modelul client/server
• Moduri de interactiune
(via canale de comunicatie)
– Orientat conexiune – se foloseste TCP
– Neorientat conexiune – se utilizeaza UDP
• Implementare
– Iterativa – fiecare cerere este tratata pe rind,
secvential
– Concurenta – cererile sint procesate concurent
• Procese copil pentru fiecare cerere de procesat
• Multiplexarea conexiunii
• Tehnici combinate
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [5]
6. Retele de calculatoare
API retea
• Necesitatea existentei unui API
pentru realizarea de aplicatii in retea
– Interfata generica pentru programare
– Suport pentru comunicatii orientate-conexiune si
prin 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
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [6]
7. Retele de calculatoare
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
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [7]
8. Retele de calculatoare
Cuprins
• Interfata de programare
bazata pe socket-uri BSD
– Caracterizare
– Creare
– Primitive
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [8]
9. Retele de calculatoare
Socket
• Socket-uri BSD (Berkeley System Distribution)
• Facilitate generala, independenta de
hardware, protocol si tipul de transmitere,
pentru comunicarea intre procese aflate 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
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [9]
10. Retele de calculatoare
Socket
• Abstractiune a unui punct terminal (end-point)
la nivelul transport
• Utilizeaza interfata de programare
I/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
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [10]
11. Retele de calculatoare
Socket
• Similar unui descriptor de fisier
• Diferente apar la creare si
la diferite operatiuni de control al socket-urilor
• Apeluri principale
– socket() creeaza un nou punct terminal al conexiunii
bind() ataseaza o adresa locala la un socket
–
listen() permite unui socket sa accepte conexiuni
–
– accept() blocheaza apelantul pina la sosirea
unei 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 socket
–
close() elibereaza conexiunea (inchide un socket)
–
shutdown() inchide directional un socket
–
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [11]
12. Retele de calculatoare
Socket
• Alte apeluri
– citire de date
read() / readv() / recvfrom() / recvmsg()
– trimitere de date
write() / writev() / sendto() / sendmsg()
– multiplexare I/O
select()
– administrarea conexiunii
fnctl() / ioctl() / setsockopt() / getsockopt()
getsockname() / getpeername()
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [12]
13. Retele de calculatoare
Socket-uri
• Implementarea
socket-urilor
in nucleul Linux
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [13]
14. Retele de calculatoare
Socket-uri|tabela de descriptori
Tabela de descriptori
Family: AF_INET
Family: AF_INET
0
Service: SOCK_STREAM
Service: SOCK_STREAM
Local IP: 193.231.30.197
1 Local IP: 193.231.30.197
Local Port: 80
Local Port: 80
2
Remote IP: 19.132.6.78
Remote IP: 19.132.6.78
3 Remote Port: 3726
Remote Port: 3726
4
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [14]
15. Retele de calculatoare
Socket-uri|creare
• Primitiva socket()
#include <sys/types.h>
#include <sys/socket.h>
int socket (int domain, int type, int protocol)
Domeniul de comunicare: Protocolul utilizat
AF_UNIX, AF_INET, pentru transmitere
AF_ROUTE (uzual: 0 pentru niv. transp.)
Modalitatea de realizare a comunicarii:
SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [15]
16. Retele de calculatoare
Socket-uri|creare
• Valoarea de retur
– Succes: descriptorul de socket creat
– Eroare: –1
• Raportarea erorii se realizeaza via errno
– EMFILE
Constante
– ENFILE
definite in
– EACCES
– EPROTONOSUPPORT errno.h
– ENOMEM
– ENOBUFFERS
– EINVAL
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [16]
17. Retele de calculatoare
Socket-uri
• Domeniul & tipul unui socket
si protocoalele folosite
AF_INET AF_INET6 AF_LOCAL AF_ROUTE
SOCK_STREAM TCP TCP Da
SOCK_DGRAM UDP UDP Da
SOCK_RAW IP IPv6 Da
AF_LOCAL ≡ AF_UNIX
(din motive istorice)
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [17]
18. Retele de calculatoare
Socket-uri
• Observatii
– Primitiva socket() aloca resursele necesare
unui 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 folosi
alte 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
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [18]
19. Retele de calculatoare
Socket-uri
• Tipuri POSIX folosite de socket-uri:
sa_family_t – familia de adrese
–
socklen_t – lungimea structurii de memorare
–
Utiliz.
in_addr_t – adresa IP (v4)
–
de
in_port_t – numarul de port
–
nucleu
• Specificarea adreselor generice
struct sockaddr { Tipul de
uint8_t sa_len; adresa
sa_family_t sa_family;
char sa_data[14];
};
Valoarea adresei
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [19]
20. Retele de calculatoare
Socket-uri
• Tipul sockaddr permite utilizarea
oricarui tip de adresare
• Exemplu: folosirea socket-urilor
pentru comunicarea dintre studenti
– Tipul de adresa: AF_STUDENTS
– Valori de adrese:
Wana ⇔ 1, Moko ⇔ 2, Tux ⇔ 3,…
– Initializarea structurii AF_STUDENTS
pentru a indica un anumit student:
struct sockaddr un_stud;
☺
un_stud.sa_family = AF_STUDENTS;
un_stud.sa_data[0] = 3;
Tux
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [20]
21. Retele de calculatoare
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_in
struct 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;
};
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [21]
23. Retele de calculatoare
Socket-uri
• Toate valorile stocate in sockaddr_in vor respecta
ordinea de codificare a retelei (network byte order)
– sin_port un numar de port TCP/IP
– sin_addr o adresa IP
• ‘h’ : host byte order ‘n’ : network byte order
• ‘s’ : short (16bit) ‘l’ : long (32bit)
uint16_t htons(uint16_t);
uint16_t ntohs(uint_16_t);
uint32_t htonl(uint32_t);
uint32_t ntohl(uint32_t);
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [23]
25. Retele de calculatoare
Socket-uri|asignarea unei adrese
• Asignarea unei adrese la un socket
existent se realizeaza cu bind()
int bind ( int sockfd,
const struct sockaddr *myaddr,
const! int addrlen );
• Se returneaza: 0 succes, –1 eroare
variabila errno contine eroarea efectiva: EBADF,
ENOTSOCK, EADDRINUSE, EINVAL, EACCESS
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [25]
27. Retele de calculatoare
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 asigneze
orice port disponibil
• In mod normal, clientul nu necesita atasarea
la un port specificat
• Alegerea oricarui port liber:
adresa.port = htons (0);
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [27]
28. Retele de calculatoare
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
utiliza in locul unei adrese IP constanta INADDR_ANY
• Conversia adreselor IP:
– int inet_aton ( char *, 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()
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [28]
29. Retele de calculatoare
Socket-uri|asignarea unei adrese
• Observatii:
– Pentru IPv6 in locul constantei INADDR_ANY
se va folosi (vezi antetul netinet/in.h):
serv.sin6.addr = in6addr_any;
– Functiile de conversie pentru IPv6 sunt:
•inet_pton()
•inet_ntop()
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [29]
30. Retele de calculatoare
Socket-uri|listen()
• Stabilirea modului pasiv de interactiune
– Adresa intotdeauna este cunoscuta
– Nucleul sistemului va trebui sa accepte cereri
de conectare directionate la adresa la care
este atasat socket-ul
• 3-way handshake Numarul
– Conexiunile multiple receptionate de conex.
vor fi plasate intr-o coada de asteptare din coada
– Se returneaza 0 = succes, –1 = eroare de astept.
int listen ( int sockfd, int backlog );
Socket TCP atasat unei adrese
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [30]
31. Retele de calculatoare
Socket-uri|listen()
• Remarci:
– Alegerea valorii backlog depinde
de aplicatie (in mod uzual 5)
– Serverele HTTP trebuie sa specifice
o valoare backlog cit mai mare
(din cauza incarcarii cu cereri multiple)
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [31]
32. Retele de calculatoare
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
Socket TCP
(mod pasiv)
int accept( int sockfd,
struct sockaddr* cliaddr,
socklen_t *addrlen );
• trebuie initial sa fie egal cu lungimea structurii cliaddr
• se va returna numarul de bytes folositi in cliaddr
– Se returneaza descriptorul de socket corespunzator
punctului terminal al clientului sau –1 = eroare
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [32]
33. Retele de calculatoare
Socket-uri|connect()
• Incercarea de a stabili o conexiune cu serverul
– Stabilirea unui punct terminal (al serverului)
– Nu necesita atasarea cu bind(), sistemul
de operare va asigna o adresa locala (IP, port)
– Se incearca stabilirea unei conexiuni
Socket TCP
• 3-way handshake
int connect( int sockfd,
const struct sockaddr *server,
socklen_t addrlen );
Contine adresa
serverului
(IP, port)
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [33]
35. Retele de calculatoare
I/O TCP|read()
• Apelul este blocant in mod normal,
read() returneaza doar cind exista date disponibile
• Citirea de la un socket TCP poate returna
mai 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 neblocanta
int read ( int sockfd, void *buf, int max );
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [35]
36. Retele de calculatoare
I/O TCP|write()
• Apelul este blocant in mod normal
• Pentru un socket neblocant,
write() poate scrie mai putin de num octeti
int write ( int sockfd, void *buf, int num );
• Erori:
– EPIPE – scriere la un socket neconectat
– EWOULDBLOCK – nu se pot accepta date
fara blocare, insa operatiunea este setata
ca fiind neblocanta
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [36]
37. Retele de calculatoare
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 */
/* trimite cererea */
write (sd, cerere, strlen (cerere));
/* asteapta raspunsul */
while ((n = read (sd, pbuf, lung)) > 0) {
pbuf += n;
lung -= n;
• Comunicarea dintre client si server
}
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [37]
38. Retele de calculatoare
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
int close ( int sockfd );
• 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
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [38]
39. Retele de calculatoare
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)
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [39]
40. Retele de calculatoare
Metaphor for Good Relationships
Copyright Dr. Laura’s Network Programming Corp.
d()
To succeed in relationships… bin
– you need to establish your own identity.
accept()
– you need to be open & accepting.
– you need to establish contacts. connect()
– you need to take things as they come, not
as you expect them. read might return 1 byte
– you need to handle problems as they arise.
s
heck for error
c
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [40]
41. Retele de calculatoare
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 portului
–
in vederea stabilirii conexiunii cu clientii: listen()
– Asteptarea realizarii unei conexiuni cu un anumit client
(deschidere pasiva): accept()
– Procesarea cererilor clientului, folosindu-se socket-ul
returnat de accept(): succesiune de read()/write()
– Inchiderea (directionata) a conexiunii cu clientul:
close(), shutdown()
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [41]
42. Retele de calculatoare
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()
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [42]
44. Retele de calculatoare
Client/server TCP
• Comunicarea orientata-conexiune
dintre server si client
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [44]
45. Retele de calculatoare
Rezumat
• Modelul client/server
• API pentru programarea in retea
• Socket-uri BSD
– Caracterizare
– Creare
– Primitive
• Modelul client/server TCP
Sabin-Corneliu Buraga 2006/2007 – www.infoiasi.ro/~busaco/ [45]