Documente Academic
Documente Profesional
Documente Cultură
2 decembrie 2003
Cuprins
1 2 Funcia WSAStartup (Windows) t Funcia socket t 2 2
2.1 2.2
3
2 3
3
Funcia bind t
3.1 3.2
4
4 4
5
Funcia connect t
4.1 4.2
5
5 6
6
Funcia listen t
5.1 5.2
6
6 6
7
Funcia accept t
6.1 6.2
7
7 7
8
7.1 7.2
8
Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8 9
9
8.1 8.2
9
Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9 9
10
9.1 9.2
10 10
11
11 Funcii pentru ordinea octeilor t t 12 Observaii asupra succesiunii funciilor pentru server / client t t 13 Tratarea erorilor
11 11 11
11 12
Sockeii sunt mijloace generalizate de comunicaie interproces deoarece: procesele comunicante t t pot rula pe alte maini, arhitectura mainii poate diferit , sistemul de operare poate diferit. Canalul s s a permite comunicaia bidirecional ntre procese, dar nu se ocup de structura datelor transmise. t t a a n general, ntr-un sistem bazat pe comunicaia cu sockei serverul urmeaz anumii pai pentru t t a t s iniierea comunicaiei: t t Creeaz un socket a Asociaz socketului o adres a a Ascult cererile clienilor a t Cnd un client dorete s iniieze o comunicaie cu serverul, acesta urmeaz si el anumii pai: s a t t a t s Creeaz un socket a Determin locaia serverului (adresa si port) a t ncepe trimiterea si/sau primirea datelor Comunicaia ntre procese prin sockei poate cu conexiune (stream) sau f r t t aa conexiune (datagram). n primul caz datele transmise sunt v zute ca secvena de bytes pe cnd n al a t doilea ca pachete (discrete) de informaie. Aceste pachete conin n general pe lng datele utile de t t a transmis si informaii header si trailer. Alegerea tipului de socket este important , deoarece ecare are t a performana si sigurana datelor diferit , iar doi sockei care comunic trebuie s e de acelai tip. t t a t a a s
Tipuri de sockei t
Stream. Sockeii de tip stream sunt siguri, adic se garanteaz primirea datelor n ordinea t a a n care au fost trimise. Exist un mecanism implementat care se ocup de datele duplicate, a a vericarea mpotriva erorilor, si controlul uxului (cu care programatorul nu are de-a face). Cnd se folosesc sockei de tip stream o conexiune este stabilit . Aceasta nseamn c dou t a a a a procese trebuie s e n mod logic de acord s comunice nainte ca informaia s e transferat a a t a a ntre ele. Aceast conexiune este meninut de ambele procese pe durata sesiunii de comunicare. a t a Datagram. Sockeii de tip datagram furnizeaz o comunicaie nesigur ntre cele dou prot a a t a a cese, aceasta nsemnnd c datele pot primite n alt ordine. Nu exist noiunea de conexiune, a a a t ecare datagram ind trimis si procesat independent. Acest lucru are multe implicaii, cea a a a t mai important ind aceea c diferite datagrame pot ajunge la aceeai destinaie pe c i diferite. a a s t a Alt implicaie de luat n seam este aceea c nu exist un control al uxului. Pachetele daa t a a a tagram sunt n general destul de mici si de obicei de lungime x . Nu se realizeaz corecia a a a t erorilor, si n cazul n care este dorit neap rat, este slab . a a a
wVersionRequested [in] Versiunea cea mai recent de Windows Sockets care poate folosit . Oca a tetul cel mai semnicativ conine partea fracionar din versiune (revision), iar cel mai t t a puin semnicativ partea ntreag . t a lpWSAData [out] Pointer c tre o structur de tip WSADATA pentru a primi detalii despre implemena a tarea sockeilor Windows. t
Valoare returnata:
n cazul sockeilor Windows la compilare trebuie inclus libr ria wsock32. (gcc <nume.c> t a a
-lwsock32)
2 Funcia socket t
Creeaz un socket cu caracteristicile cerute de tipul de comunicare dorit. a
2.1 Apelul Unix socket
#include <sys/types.h> #include <sys/socket.h> int socket(int family, int type, int protocol);
Parametri:
family
poate avea diferite valori (AF vine de la address family). Dou dintre ele ar : a AF_UNIX pentru protocoalele interne UNIX AF_INET pentru protocoalele TCP/IP
type
tipul socket-ului:
SOCK_STREAM socket orientat pe conexiune SOCK_DGRAM socket datagram (f r conexiune) a aa SOCK_RAW socket direct (pentru comunicarea la nivel IP) protocol are de regul valoarea 0. Exist unele aplicaii specializate n care trebuie specicat a a t a o valoare dependent de tipul de socket si familia de protocoale folosite. Exemplu: a IPPROTO_TCP (sockei orientai conexiune), IPPROTO_UDP (sockei f r conexiune) t t t aa
Valoare returnata:
caz de eroare.
2.2 Apelul Windows socket
#include <Winsock2.h> SOCKET socket( int af, int type, int protocol );
Parametri:
af type
[in] Address family (vezi Unix socket). [in] Specicarea tipului pentru noul socket: SOCK_STREAM sau SOCK_DGRAM. (vezi Unix socket)
protocol [in] Protocolul ce va folosit cu socketul, specic familiei indicate. Exemplu: IPPROTO_TCP (sockei orientai conexiune), IPPROTO_UDP (sockei f r conexiune). Parametrul este t t t aa totdeauna setat la 0 pentru IrDA.
Valoare returnata:
Dac nu apar erori, funcia returneaz un descriptor corespunz tor noului socket. a t a a Altfel se returneaz valoarea INVALID_SOCKET si un cod de eroare specic poate obinut cu a t ajutorul funciei WSAGetLastError. t
3 Funcia bind t
Asociaz unui socket o adres (realizeaz leg tura ntre un socket creat anterior si un punct nal de a a a a comunicare). Este necesar att n cazul comunic rii cu conexiune ct si n cazul comunic rii f r a a a aa conexiune.
3.1 Apelul Unix bind
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
Parametri:
descriptor de socket obinut printr-un apel socket anterior. t pointer la o structur de adres specic ec rei familii de protocoale. a a a a lungimea structurii de adres . a Returneaz 0 n caz de succes sau -1 n caz de eroare. a
Valoare returnata:
struct sockaddr{ u_short sa_family; char sa_data[14]; }; Coninutul celor 14 octei de date este precizat n cazul familiei TCP/IP prin urm toarea structur t t a a denit n <netinet/in.h>: a struct in_addr{ u_long s_addr; /* 32-bit netid/hostid (network byte ordered) */ }; struct sockaddr_in{ short sin_family; /* AF_INET */ u_short sin_port; /* 16-bit port number (network byte ordered) */ struct in_addr sin_addr; /* 32-bit netid/hostid (network byte ordered)*/ char sin_zero[8]; /* unused */ };
Exemplu de folosire:
s name namelen
[in] Descriptor ce identic un socket creat prin apelul funciei socket. a t [in] Adresa care i se va asigna socketului. [in] Lungimea valorii parametrului name n bytes.
Valoare returnata:
n caz de succes funcia returneaz zero, altfel returneaz SOCKET_ERROR, si t a a un cod de eroare specic poate v zut cu WSAGetLastError. a
struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; };
Observaii t
1. n Windows Sockets 2, parametrul name nu este interpretat n mod strict ca un pointer la o structur de tip sockaddr. Se face acest cast pentru compatibilitatea cu Windows Sockets 1.1. a (vezi exemplu de folosire) 2. n cazul n care nu ne intereseaz ce adres local va asignat , se va specica valoarea INAa a a a DDR_ANY pentru adres (vezi exemplu) si va alocat automat o adres disponibil . a a a a
Exemplu de folosire:
struct sockaddr_in echoServAddr; echoServAddr.sin_family = AF_INET; echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); echoServAddr.sin_port = htons(echoServPort); if(bind(sock,(struct sockaddr *) &echoServAddr, sizeof(echoServAddr))<0){ fprintf(stderr,"eroare: %d\n",WSAGetLastError()); }
4 Funcia connect t
Iniiaz o conexiune (pentru protocoalele cu conexiune), adic stabilete o leg tur ntre un proces clit a a s a a ent si server. Execuia apelului implic schimbul unor mesaje ntre cele dou sisteme pentru stabilirea t a a parametrilor leg turii. a
4.1 Apelul Unix connect
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, const struct sockaddr *myaddr, int addrlen);
Parametri: asem n tori ca semnicaie cu cei de la bind, cu excepia faptului c myaddr trebuie s a a t t a a
conin adresa serverului la care clientul vrea s se conecteze. t a a Revenirea din apel se face numai dup stabilirea cu succes a leg turii (valoarea a a 0) sau dac se produce o eroare (valoarea -1). a
Valoare returnata:
conin adresa serverului la care clientul vrea s se conecteze. t a a n caz de succes returneaz zero. Altfel, returneaz SOCKET_ERROR, si un cod a a de eroare specic poate v zut cu ajutorul WSAGetLastError. a
Valoare returnata:
5 Funcia listen t
Preg tete socketul pentru a primi conexiuni (numai pentru protocoalele cu conexiune). a s
5.1 Apelul Unix listen
backlog
Cte apeluri pot acceptate n timp ce serverul ateapt terminarea unui accept nceput s a (se consum un anumit timp pentru ca serverul s efectueze operaiile necesare la accepa a t tarea unei cereri). Tradiional valoarea utilizat pentru backlog este 5, maximul admis n t a implement rile curente. a Zero n caz de succes si -1 n caz de eroare.
Valoare returnata:
backlog
[in] Lungimea maxim a cozii de conexiuni n curs de acceptare. Dac este setat la a a SOMAXCONN, backlog va setat la valoarea maxim posibil . Nu exist o metod a a a a a standard pentru a obine valoarea backlog efectiv . t a
n caz de succes funcia returneaz zero. Altfel se ntoarce SOCKET_ERROR. t a Un cod de eroare detaliat se poate obine prin apelul funciei WSAGetLastError. t t
Valoare returnata:
6 Funcia accept t
Accept o conexiune; un canal de comunicaie este creat ntre cel ce a iniiat si cel ce a acceptat a t t conexiunea (numai pentru protocoalele cu conexiune).
6.1 Apelul Unix accept
#include <sys/types.h> #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, int *addrlen);
Parametri:
Descriptor de socket pe care s-a f cut listen. a Conine dup apel adresa procesului client care s-a conectat. t a [in,out] Dimensiune addr - vezi observaie important ! t a
a Funcia returneaz e eroare (-1), e descriptorul de socket al unui socket nou t creat, cu aceleai proprieti ca si sockfd. Prin socketul returnat se va desf sura comunicaia ntre s at a t server si clientul acceptat.
Valoare returnata:
s addr addrlen
[in] Descriptor de socket pe care s-a f cut listen. a [out] Pointer opional c tre un buffer n care se pune adresa clientului care s-a conectat. t a [in,out] Pointer opional c tre un ntreg care conine lungimea valorii lui addr. (vezi t a t observaie important !) t a
n caz de succes se returneaz o valoare de tip SOCKET care reprezint descripa a torul pentru noul socket. Prin socketul returnat se va desf sura comunicaia ntre server si clientul a t acceptat. n caz de eroare se ntoarce INVALID_SOCKET, iar un cod de eroare detaliat se poate obine prin apelul funciei WSAGetLastError. t t
Valoare returnata: Observaie: t
Funcia accept poate bloca programul apelant pn cnd o conexiune este prezent dac nu exist t a a a a cereri de conectare n coad , si socket-ul este marcat ca blocant. Dac socketul nu e blocant si nu a a exist conexiuni n ateptare, accept returneaz eroare. a s a
Observaie importanta: t
ntregul referit de addrlen trebuie s conin iniial dimensiunea structurii c tre care puncteaz addr. a t a t a a La return va conine lungimea efectiv a adresei returnate. t a
int send(int sockfd, const void *buff, size_t nbytes, int flags); int recv(int sockfd, void *buff, size_t nbytes, int flags);
Parametri:
sockfd buff
Descriptor corespunz tor unui socket conectat. a [in] Buffer ce conine datele de transmis (send) / [out] Buffer pentru datele ce vor t primite (recv). [in] Lungimea n octei a datelor din buf (send) / [in] Lungimea n octei a lui buf (recv). t t [in] Flag se specic modul n care se face transmiterea/primirea datelor. Se poate seta a folosind OR pe bii cu diferite valori: t Pentru send: MSG_DONTROUTE, MSG_OOB (date de tip OOB), etc. Pentru recv: MSG_PEEK, MSG_OOB, etc.
nbytes flags
Valoare returnata:
Send / Recv returneaz num rul de caractere trimise / primite sau -1 n caz de a a
eroare. Apelurile Unix read si write pot de asemenea folosite de protocoalele cu conexiune pentru a transmite si primi date. Se folosesc la fel ca si n cazul ierelor. s
Observaie: t
7.2 Windows
int send( SOCKET s, const char* buf, int len, int flags ); int recv( SOCKET s, char* buf, int len, int flags );
Parametri:
s buf
[in] Descriptor corespunz tor unui socket conectat. a [in] Buffer ce conine datele de transmis (send) / [out] Buffer pentru datele ce vor t primite (recv). [in] Lungimea n octei a datelor din buf (send) / [in] Lungimea n octei a lui buf (recv). t t [in] Flag se specic modul n care se face transmiterea/primirea datelor. Se poate seta a folosind OR pe bii cu urm toarele valori: t a Pentru send: MSG_DONTROUTE, MSG_OOB (date de tip OOB). Pentru recv: MSG_PEEK, MSG_OOB.
len flags
Valoare returnata:
n caz de succes, send returneaz num rul total de octei trimii, care poate mai a a t s mic dect len, altfel SOCKET_ERROR. n caz de succes recv returneaz num rul de octei primii. Dac conexiunea a fost nchis , se a a t t a a retuneaz zero. La eroare, se returneaz SOCKET_ERROR si informaii detaliate se obin cu ajutorul a a t t WSAGetLastError.
int sendto(int sd, const void *buf, size_t len, int flags, struct sockaddr *to, int tolen); int recvfrom(int sd, void *buf, size_t len, int flags, struct sockaddr *from, int fromlen);
8.2 Windows
int sendto( SOCKET sd, const char* buf, int len, int flags, const struct sockaddr* to, int tolen ); int recvfrom( SOCKET sd, char* buf, int len, int flags, struct sockaddr* from, int* fromlen );
10
[in] Pointer c tre o structur de tip sockaddr care conine adresa socketului destinaie. a a t t [in] Dimensiunea adresei din to. [out] Pointer c tre un buffer dintr-o structur de tip sockaddr care va conine adresa sursei. a a t [in, out] Pointer c tre dimensiunea bufferului from. a
int closesocket( SOCKET s ); n caz de succces se retuneaz zero, altfel SOCKET_ERROR si WSAGetLastError pentru cod de a eroare specic.
11
Primele dou funcii convertesc valori lungi, respectiv scurte, din reprezentarea intern (n calculator) a t a n reprezentarea din reea iar celelalte dou funcii fac conversia n sens invers. Valorile convertite se t a t consider ntregi, cu convenia c un ntreg scurt se reprezint pe 16 bii iar unul lung pe 32 bii. a t a a t t
[WSAStartup->] socket -> bind -> listen (-> accept -> send/recv)* -> close [-> WSACleanup]
Client pentru un protocol cu conexiune:
[WSAStartup->] socket -> bind -> connect (-> send/recv)* -> close [-> WSACleanup]
Server pentru un protocol fara conexiune:
[WSAStartup->] socket -> bind (-> sendto/recvfrom)* -> close [-> WSACleanup]
Client pentru un protocol fara conexiune:
[WSAStartup->] socket -> bind (-> sendto/recvfrom)* -> close [-> WSACleanup]
13 Tratarea erorilor
13.1 Tratarea erorilor n Unix
Este realizat cu ajutorul variabilei errno care este setat de apelurile de sistem (i de unele funcii a a s t de bibliotec ) pentru a indica ce eroare a ap rut. a a #include <errno.h> extern int errno; Mai exist de asemenea si funcia perror care aeaz la stderr nti sirul s si apoi un mesaj cu ultima a t s a eroare produs . a void perror(const char *s);
13.2 Tratarea erorilor n Windows
Este realizat cu ajutorul funciei GetLastError, care returneaz ultima eroare ap rut . a t a a a DWORD GetLastError(void); Pentru cazul funciilor care lucreaz cu sockei se folosete funcia WSAGetLastError, care returt a t s t neaz eroarea ap rut la ultima operaie cu sockei. a a a t t int WSAGetLastError(void);
12