Servidor concurrent amb connexió: select() i fork() en xarxes TCP
Servidor concurrent amb connexió
Amb algorisme d'un sol procés:
1. Crea un socket (msock) i vincula'l a una adreça/port
2. Obre el socket en mode passiu
3. Configura el msock a la llista de control
4. Repeteix {
5. Select
6. Si hi ha activitat a msock, crea un nou socket ssock i
afegeix-lo a la llista.
7. Per a cada socket de ssock
8. Si hi ha activitat a ssock {llegeix i escriu}
9. Finalitza i elimina els ssocks de la llista si cal
10. Vés a 4.
Crides al sistema utilitzades:
msock=socket(...); bind(...); listen(...);
FD_ZERO(list);
FD_SET(msock, list);
do {ret = select(..., list, ...)
if FD_ISSET(msock, list) {
ssock = accept(msock);
FD_SET(ssock, list) }
for i in list {
if FD_ISSET(i, list) {
read(ssock);
write(ssock) }
if end_service(i) {
close(ssock);
FD_CLEAR(ssock,...) }}
} while(true)
En aquest tipus de servidors només hi ha un procés que serveix simultàniament totes les sol·licituds dels clients.
-> És útil quan hi ha molts clients que sol·liciten el mateix recurs.
-> Si hi ha una alta activitat dels clients, el rendiment del servidor disminueix ràpidament.
La crida al sistema select() s'utilitza per detectar l'activitat dels sockets.
Els sockets disponibles per enviar o els sockets amb dades detectades
es poden accedir -> sense bloqueig
htonl() converteix l'enter sense signe hostlong de l'ordre de bytes de l'host a l'ordre de bytes de xarxa.
htons() converteix l'enter curt sense signe hostshort de l'ordre de bytes de l'host a l'ordre de bytes de xarxa.
ntohl() converteix l'enter sense signe netlong de l'ordre de bytes de xarxa a l'ordre de bytes de l'host.
Servidor concurrent amb connexió (fork)
Algorisme del procés mestre:
1. Crea un socket (msock) i vincula'l a una adreça/port
2. Obre msock en mode passiu
3. Accepta una nova sol·licitud
4. Crea un procés esclau per atendre la sol·licitud
5. Tanca el nou socket i vés a 3.
Algorisme del procés esclau:
1. Tanca msock
2. Repeteix {
Llegeix del socket (sol·licitud);
Envia al socket (resposta) }
3. Tanca el socket ssock.
4. Finalitza
//MESTRE
msock=socket(PF_INET, SOCK_STREAM, PROT_TCP)
bind(msock, ads)
listen(msock, len_wait_queue)
do{
ssock = accept(msock)
child_pid=fork() //crea l'esclau
if (child_pid==0){ //el fill rep 0; el pare rep l'identificador del procés fill
child();
exit();
}
} while(true)
child() //ESCLAU
do {
read(ssock, ...)
write(ssock, ...)
} while (no end)
close(ssock)