Observatie: Dupa cum reiese si din materialele referite mai sus, este important de remarcat ca primitivele numite "socket" in Java sunt destul de diferite de corespondentele lor din C. De fapt, Java abstractizeaza socket-urile reale, punand la dispozitia utilizatorului stream-uri prin care se poate lucra in modul obisnuit din Java.
Din punctul de vedere al modului in care accepta conexiunile de la clienti, exista doua modalitati de a proiecta un server. Alegerea metodei se face tinand seama de cerintele sistemului software ce se doreste a fi implementat si de considerente de eficienta a acestuia.
Un server iterativ poate deservi un singur client la un moment dat. Daca in timp ce un client este deservit, apar alte cereri de conexiune, acestea vor fi puse intr-o coada de asteptare. Este posibil ca la un moment dat coada sa se umple, iar noile cereri sa fie respinse.
Secventa urmatoare de (pseudo)cod arata modul de implementare in C a unui astfel de server:
int sockfd, newsockfd; if ((sockfd=socket(...)) < 0) { printf ("error ..."); exit(1); } if (bind(sockfd,...) < 0) { printf ("error ..."); exit(1); } if (listen(sockfd,5) < 0) { printf ("error ..."); exit(1); } for (;;) { newsockfd = accept(sockfd, ...); /* blocare pentru asteptare cereri*/ if (newsockfd < 0) { printf ("error ..."); exit(1); } process(newsockfd); /*deservire cerere*/ close (newsockfd); }Se observa ca o noua cerere nu este acceptata pana cand cererea in curs nu a fost deservita.
Un server concurent este scris in asa fel incat poate deservi mai multi clienti la un moment dat. Principiul este simplu, si se bazeaza pe crearea cate unui proces fiu pentru deservirea fiecarui client. Serverele concurente sunt cele mai raspandite modalitati de oferire a serviciilor in retea.
Programul de mai jos arata un exemplu de astfel de server:
int sockfd, newsockfd; if ((sockfd=socket(...)) < 0) { printf ("error ..."); exit(1); } if (bind(sockfd,...) < 0) { printf ("error ..."); exit(1); } if (listen(sockfd,5) < 0) { printf ("error ..."); exit(1);} } for (;;) { newsockfd=accept(sockfd, ...); /* blocare pentru asteptare cereri*/ if (newsockfd < 0) { printf ("error ..."); exit(1); } if (fork()==0) /* procesul fiu */ { close(sockfd); process(newsockfd); /*procesare cerere*/ exit(0); } close (newsockfd); /* parinte */ }Se observa ca atat parintele cat si fiul inchid socket-ul de care nu mai au nevoie: parintele inchide noul descriptor primit dupa accept() pentru ca el nu doreste sa trimita sau sa primeasca date prin intermediul sau, iar fiul inchide socket-ul initial, deoarece nu asteapta conexiuni noi din retea.
Daca este necesar, se pot introduce metode de limitare a numarului de clienti care se pot conecta, prin conditionarea prin program a efectuarii apelului accept() de numarul de clienti deja conectati.