Sunteți pe pagina 1din 12

Sockei t

2 decembrie 2003

Cuprins
1 2 Funcia WSAStartup (Windows) t Funcia socket t 2 2

2.1 2.2
3

Apelul Unix socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apelul Windows socket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 3
3

Funcia bind t

3.1 3.2
4

Apelul Unix bind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apelul Windows bind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 4
5

Funcia connect t

4.1 4.2
5

Apelul Unix connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apelul Windows connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 6
6

Funcia listen t

5.1 5.2
6

Apelul Unix listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apelul Windows listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6 6
7

Funcia accept t

6.1 6.2
7

Apelul Unix accept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apelul Windows accept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 7
8

Apeluri pentru transferuri cu conexiune

7.1 7.2
8

Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8 9
9

Apeluri pentru transferuri fara conexiune

8.1 8.2
9

Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9 9
10

Funcia de nchidere socket t

9.1 9.2

Apelul Unix close . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Apelul Windows closesocket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10 10
11

10 Funcia WSACleanup (Windows) t

11 Funcii pentru ordinea octeilor t t 12 Observaii asupra succesiunii funciilor pentru server / client t t 13 Tratarea erorilor

11 11 11

13.1 Tratarea erorilor n Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.2 Tratarea erorilor n Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

1 Funcia WSAStartup (Windows) t


Iniializeaz folosirea bibliotecii WS2_32.DLL de un proces. WSAStartup trebuie s e prima funcie t a a t apelat cnd se dorete lucrul cu sockei. a s t int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData );
Parametri:

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:

Funcia returneaz zero n caz de succes si un cod de eroare altfel. t a

Exemplu de apel: (pentru versiunea 2.0)

if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { fprintf(stderr,"WSAStartup() failed"); exit(1); }


Observaie: t

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:

Descriptor de socket care se utilizeaz la fel ca un descriptor de ier sau -1 n a s

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:

sockfd myaddr addrlen

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:

Structura de adresa se g se te n <sys/socket.h>: a s

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:

vezi exemplul pentru Windows.

3.2 Apelul Windows bind

int bind( SOCKET s, const struct sockaddr* name, int namelen );


Parametri:

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

Structura de adresa este identic cu cea din UNIX. 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:

4.2 Apelul Windows connect

int connect( SOCKET s, const struct sockaddr* name, int namelen );


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 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

int listen(int sockfd, int backlog);


Parametri:

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:

5.2 Apelul Windows listen

int listen( SOCKET s, int backlog );


Parametri:

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:

sockfd addr addrlen

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:

6.2 Apelul Windows accept

SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen );


Parametri:

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

7 Apeluri pentru transferuri cu conexiune


7.1 Unix

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.

8 Apeluri pentru transferuri fara conexiune


8.1 Unix

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

Parametri: sd, buf, len, flags - idem send / recv.

to tolen from fromlen

[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

Valoare retunata: idem send / recv.

9 Funcia de nchidere socket t


nchide canalul de comunicaie si distruge socketul. t
9.1 Apelul Unix close

int close(int sockfd); n caz de succces se returneaz zero, altfel -1. a


9.2 Apelul Windows closesocket

int closesocket( SOCKET s ); n caz de succces se retuneaz zero, altfel SOCKET_ERROR si WSAGetLastError pentru cod de a eroare specic.

10 Funcia WSACleanup (Windows) t


Funcia ncheie utilizarea bibliotecii WS2_32.DLL. t int WSACleanup(void); Returneaz zero n caz de succes si SOCKET_ERROR altfel (WSAGetLastError pentru erori specia ce).

11 Funcii pentru ordinea octeilor t t


Sunt identice att n Windows ct si n Linux. Sunt necesare datorit diferenelor arhitecturale ntre a t calculatoare si conveniei de transmitere a informaiilor multioctet n reea. t t t u_long htonl(u_long hostlong); u_short htons(u_short hostshort); u_long ntohl(u_long netlong); u_short ntohs(u_short netshort);

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

12 Observaii asupra succesiunii funciilor pentru server / client t t


Server pentru un protocol cu conexiune:

[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

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