Sunteți pe pagina 1din 24

6.

Programarea aplicaţiilor de reţea


Socket-uri
 Mecanism de comunicaţie între procese (IPC – Inter-Process
Communication)
– UNIX domain vs. INTERNET domain
 Interfaţă de acces la protocoalele de comunicaţie
– Application Programming Interface (API)
– set de apeluri sistem pentru accesul la serviciile de comunicaţie în reţea
 Introduse pentru prima dată în versiunea 4.2 a Berkeley
Software Distribution (BSD)
 Standard de facto pentru programarea aplicaţiilor de reţea

© Ion BICA 2
Caracteristicile socket-urilor
 Domeniu
– AF_UNIX: formatul de adresa conţine un nume de fişier
– AF_INET: formatul de adresa conţine o adresa IP şi număr de port
 Tip
– circuit virtual
– datagrama
 Protocol
– TCP (circuit virtual)
– UDP (datagrama)
 Mod de comunicare
– Client–Server
• serverul aşteaptă cereri de la clienţi
– Peer–to–Peer
• procesele sunt simetrice

© Ion BICA 3
Socket API
 socket(): creează un socket de un anumit tip
 bind(): realizează legătura între un socket şi o adresă de conectare
 listen(): specifică numărul de cereri de conexiune care pot fi ţinute
în aşteptare la nivelul serverului
 accept(): folosit de server pentru a accepta o cerere de conexiune
de la un client
 connect(): folosit de client pentru a solicita stabilirea legăturii cu un
server
 send(), sendto(): transmitere date
 recv(), recvfrom(): recepţionare date
 shutdown(): închidere conexiune
 close(): dealocare resurse

© Ion BICA 4
Socket-uri TCP

© Ion BICA 5
socket()
#include <sys/types.h>
#include <sys/socket.h>

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

 domain:
– AF_UNIX: comunicaţie între procese de pe acelaşi sistem
– AF_INET: comunicaţie între procese din reţea
 type:
– SOCK_STREAM: orientat conexiune (circuit virtual)
– SOCK_DGRAM: neorientat conexiune (datagram)
– SOCK_SEQPACKET: orientat conexiune folosind mesaje de dimensiune
maximă (de regulă, aceasta obţine nu este suportată)
 protocol:
– de obicei este zero; protocolul este stabilit prin intermediul tipului
 returnează un descriptor de socket (socket ID) sau -1 în caz de eroare

© Ion BICA 6
bind()
#include <sys/types.h>
#include <sys/socket.h>

int bind (int sid, struct sockaddr *addrPtr, int len);

 sid: descriptorul socket-ului


 addrPtr: pointer către o structură ce descrie adresa de conectare a
serverului
 len: sizeof (*addrPtr )

© Ion BICA 7
sockaddr
 Socket-uri INTERNET
struct sockaddr_in {
sa_family_t sin_family; // = AF_INET
in_port_t sin_port; // numărul portului
struct in_addr sin_addr; // adresa IP
}

 Socket-uri UNIX
struct sockaddr_un {
uint8_t sun_length; //
short sun_family; // = AF_UNIX
char sun_path [126];// numele fişierului
}

© Ion BICA 8
listen()
#include <sys/types.h>
#include <sys/socket.h>

int listen (int sid, int size);

 sid: descriptorul socket-ului


 size: numărul maxim de cereri de conexiune care pot fi ţinute în aşteptare
(de regulă, este limitat la 5 pe unele sisteme Unix)

© Ion BICA 9
accept()
#include <sys/types.h>
#include <sys/socket.h>

int accept (int sid, struct sockaddr *addrPtr, int *lenPtr);

 sid: descriptorul socket-ului


 addrPtr: pointer către o structură ce descrie adresa de conectare a
clientului
 lenPtr: pointer către o valoare ce specifică dimensiunea structurii sockaddr
 returnează descriptorul de socket şi adresa clientului care s-a conectat la
server

© Ion BICA 10
connect()
#include <sys/types.h>
#include <sys/socket.h>

int connect (int sid, struct sockaddr *addrPtr, int len);

 sid: descriptorul socket-ului


 addrPtr: pointer către o structură ce descrie adresa pentru conectare la
server
 len: sizeof (*addrPtr )

© Ion BICA 11
send()
#include <sys/types.h>
#include <sys/socket.h>

int send (int sid, const char *bufferPtr, int len, int flag);

 sid: descriptorul socket-ului


 bufferPtr: pointer către buffer-ul în care se află datele de transmis
 len: numărul de octeţi din buffer
 flag:
– 0: default
– MSG_OOB: mesaj prioritar (out-of-band)
 returnează numărul de octeţi efectiv transmişi sau -1 în caz de eroare

© Ion BICA 12
recv()
#include <sys/types.h>
#include <sys/socket.h>

int recv (int sid, char *bufferPtr, int len, int flag);

 sid: descriptorul socket-ului


 bufferPtr: pointer către buffer-ul în care se vor depune datele recepţionate
 len: câţi octeţi se doreşte a se recepţiona
 flag:
– 0: default
– MSG_OOB: mesaj prioritar (out-of-band)
– MSG_PEEK: citeşte mesajul fără al şterge din bufferul de recepţie
 returnează numărul de octeţi efectiv recepţionaţi sau -1 în caz de eroare

© Ion BICA 13
shutdown()
#include <sys/types.h>
#include <sys/socket.h>

int shutdown (int sid, int how);

 sid: descriptorul socket-ului


 închide transmisia (how = 1 / 2) sau recepţia (how = 0 / 2)

© Ion BICA 14
Alte apeluri sistem
 gethostname()
– returnează numele calculatorului
 gethostbyname(), gethostbyaddr()
– conversia nume in adresa IP şi invers
– resolver DNS
 htons(), htonl(), ntohs(), ntohl()
– conversie între diferite formate de reprezentare
– network = big endian
– host: SPARC = big endian, Intel = little endian
 inet_ntop(), inet_pton()
– conversie adrese IP în format printabil şi invers

© Ion BICA 15
Exemplu: TCP Server (versiunea iterativa)
int listenSocket, connectSocket;
struct sockaddr_in serverAddr, clientAddr;

listenSocket = socket (AF_INET, SOCK_STREAM, 0);

bzero (&serverAddr, sizeof (serverAddr));


serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.saddr = htonl(INADDR_ANY); // any interface
serverAddr.sin_port = htons (3555);

bind (listenSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));


listen (listenSocket, 10);

while(1) {
int clientAddrLength = sizeof(clientAddr);
connectSocket = accept (listenSocket, (struct sockaddr *) &clientAddr,
&clientAddrLength);

// send and receive operations on connectSocket. . .

close (connectSocket);
}
close (listenSocket);

© Ion BICA 16
Exemplu: TCP Server (versiunea concurenta)
int listenSocket, connectSocket;
struct sockaddr_in serverAddr, clientAddr;

listenSocket = socket (AF_INET, SOCK_STREAM, 0);

bzero (&serverAddr, sizeof (serverAddr));


serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.saddr = htonl(INADDR_ANY); // any interface
serverAddr.sin_port = htons (3555);

bind (listenSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));


listen (listenSocket, 10);

while(1) {
int clientAddrLength = sizeof(clientAddr);
connectSocket = accept (listenSocket, (struct sockaddr *) &clientAddr,
&clientAddrLength);
if (!fork()) { // this is the child process
close (listenSocket); // child doesn't need the listener

// send and receive operations on connectSocket. . .

close (connectSocket);
exit(0);
}

close (connectSocket); // parent doesn't need this


}
close (listenSocket);

© Ion BICA 17
Exemplu: TCP Client
int socketDescriptor;
struct sockaddr_in serverAddr;

socketDescriptor = socket (AF_INET, SOCK_STREAM, 0);

bzero (&serverAddr, sizeof (serverAddr));


serverAddr.sin_family = AF_INET;
// host IP # in dotted decimal format!
inet_pton (AF_INET , serverName , serverAddr.sin_addr);
serverAddr.sin_port = htons (3555);

connect (socketDescriptor, (struct sockaddr *) &serverAddr,


sizeof(serverAddr));

// send and receive operations on socketDescriptor. . .

close (socketDescriptor);

© Ion BICA 18
Socket-uri UDP

© Ion BICA 19
sendto()
#include <sys/types.h>
#include <sys/socket.h>

int sendto (int sid, const void *bufferPtr,


size_t bufferLength, int flag,
struct sockaddr *addrPtr, socklen_t addrLength);

 sid: descriptorul socket-ului


 bufferPtr: pointer către buffer-ul în care se află datele de transmis
 bufferLength: numărul de octeţi din buffer
 flag:
– 0: default
– MSG_OOB: mesaj prioritar (out-of-band)
 addrPtr: pointer către o structură ce descrie adresa la care trebuie trimise
datele
 addrLength: sizeof (*addrPtr )
 returnează numărul de octeţi efectiv transmişi sau -1 în caz de eroare
© Ion BICA 20
recvfrom()
#include <sys/types.h>
#include <sys/socket.h>

int recvfrom (int sid, const void *bufferPtr,


size_t bufferLength, int flag,
struct sockaddr *addrPtr, socklen_t *addrLengthPtr);

 sid: descriptorul socket-ului


 bufferPtr: pointer către buffer-ul în care se vor depune datele recepţionate
 bufferLength: câţi octeţi se doreşte a se recepţiona
 flag:
– MSG_OOB: mesaj prioritar (out-of-band)
– MSG_PEEK: citeşte mesajul fără al şterge din bufferul de recepţie
 addrPtr: pointer către o structură ce descrie adresa de la care au fost
recepţionate datele
 addrLengthPtr: pointer către o valoare ce specifică dimensiunea structurii
sockaddr
 returnează numărul de octeţi efectiv recepţionaţi sau -1 în caz de eroare

© Ion BICA 21
Exemplu: UDP Server
int socketId;
struct sockaddr_in serverAddr, clientAddr;

socketId = socket (AF_INET, SOCK_DGRAM, 0);

bzero (&serverAddr, sizeof (serverAddr));


serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.saddr = htonl(INADDR_ANY); // any interface
serverAddr.sin_port = htons (3555);

bind (socketId, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

int clientAddrLength = sizeof(clientAddr);


// receive from a client
recvfrom (socketId, buffer, sizeof(buffer), 0,
(struct sockaddr *) &clientAddr, &clientAddrLength);
// reply to the client
sendto (socketId, buffer, sizeof(buffer), 0,
(struct sockaddr *) &clientAddr, sizeof(clientAddr));

close (socketId);

© Ion BICA 22
Exemplu: UDP Client
int socketId;
struct sockaddr_in serverAddr;

socketId = socket (AF_INET, SOCK_DGRAM, 0);

bzero (&serverAddr, sizeof (serverAddr));


serverAddr.sin_family = AF_INET;
// host IP # in dotted decimal format!
inet_pton (AF_INET , serverName , serverAddr.sin_addr);
serverAddr.sin_port = htons (3555);

int serverAddrLength = sizeof(serverAddr);


// send data to the server
sendto (socketId, buffer, sizeof(buffer), 0,
(struct sockaddr *) &serverAddr, sizeof(serverAddr));
// receive data from the server
recvfrom (socketId, buffer, sizeof(buffer), 0,
(struct sockaddr *) &serverAddr, &serverAddrLength);

close (socketId);

© Ion BICA 23
© Ion BICA 24

S-ar putea să vă placă și