In molte applicazioni Internet, client e server comunicano per un ampio periodo di tempo, con il client che inoltra una serie di richieste e il server che risponde a ciascuna.
A seconda dell’applicazione e di come questa viene usata, la serie di richieste potrebbe essere effettuata in sequenza, periodicamente a intervalli regolari o a intermittenza.
Quando questa interazione client-server ha luogo su TCP, gli sviluppatori delle applicazioni devono prendere una decisione importante: ciascuna coppia richiesta/risposta deve essere inviata su una connessione TCP separata o devono essere inviate tutte sulla stessa connessione TCP?
Nel primo approccio si dice che l’applicazione usa connessioni non persistenti, mentre nel secondo, usa connessioni persistenti.
Per avere una maggiore comprensione degli aspetti progettuali, esaminiamo i vantaggi e gli svantaggi delle connessioni persistenti nel contesto di un’applicazione specifica, cioè HTTP, che può usare entrambi i tipi di connessioni.
Sebbene nella sua modalità di default usi le connessioni persistenti, i client e i server HTTP possono essere configurati per usare quelle non persistenti.
HTTP con connessioni non persistenti
Seguiamo passo dopo passo il trasferimento di una pagina web dal server al client nel caso di connessioni non persistenti.
Supponiamo che la pagina consista di un file base HTML, e di 10 immagini JPEG, e che tutti gli undici oggetti risiedano sullo stesso server.
Ipotizziamo che l’URL del file base HTML sia
http://www.nomesito.it/paginasito/home.index
Ecco cosa avviene:
- il processo client HTTP inizializza una connessione TCP con il server www.nomesito.it sulla porta 80, che è la porta di default per HTTP. Associate alla connessione TCP, ci saranna una socket al client e una al server.
- Il client HTTP, tramite la propria socket, invia al server un messaggio di richiesta HTTP che include il percorso /paginasito/home.index.
- Il processo server HTTP riceve il messaggio di richiesta attraverso la propria socket associata alla connessione, recupera l’oggetto /paginasito/home.index dalla memoria (centrale o di massa), lo incapsula in un messaggio di risposta HTTP che viene inviato al client attraverso la socket.
- Il processo server HTTP comunica a TCP di chiudere la connessione. Questi, in realtà, non termina la connessione fino a quando non è certo che il client abbia ricevuto integro il messaggio di risposta.
- Il client HTTP riceve il messaggio di risposta. La connessione TCP termina. Il messaggio indica che l’oggetto incapsulato è un file HTML.
Il client estrae il file dal messaggio di risposta, esamina il file HTML e trova i riferimenti ai 10 oggetti JPEG. - Vengono quindi ripetuti i primi quattro passi per ciascuno degli oggetti JPEG referenziati.
Quando il browser riceve la pagina web, la visualizza all’utente.
Due browser diversi possono interpretare (e quindi mostrare all’utente) una stessa pagina web secondo modalità leggermente diverse.
HTTP non ha niente a che vedere con l’interpretazione della pagina web da parte di un client. Le specifiche HTTP definiscono solo il protocollo di comunicazione tra il programma HTTP client e il programma HTTP server.
I passi sopra riportati illustrano l’utilizzo di connessioni non persistenti, in cui ogni connessione TCP viene chiusa dopo l’invio dell’oggetto da parte del server: vale a dire che ciascuna trasporta soltanto un messaggio di richiesta e un messaggio di risposta.
Pertanto, in questo esempio, quando l’utente richiede una pagina web, vengono generate 11 connessioni TCP.
Nei passi descritti sopra, abbiamo tralasciato il fatto che il client ottenga le 10 JPEG su 10 connessioni TCP in serie anziché in parallelo.
Infatti, gli utenti possono configurare i moderni browser per controllare il grado di parallelismo.
In modalità di default, la maggior parte dei browser apre da 5 a 10 connessioni TCP parallele, e ciascuna di queste gestisce una transazione richiesta-risposta.
Se lo desidera, l’utente può impostare il numero di connessioni parallele a 1, caso in cui le 10 connessioni vengono stabilite in serie.
Prima di proseguire, facciamo un calcolo approssimativo per stimare la quantità di tempo che intercorre tra la richiesta di un file base HTML da parte del client e il momento in cui l’intero file viene ricevuto dal client.
A questo scopo, definiamo il round trip time (RTT), che rappresenta il tempo impiegato da un piccolo pacchetto per viaggiare dal client al server e poi tornare al client.
RTT include i ritardi di propagazione, di accodamento nei router e nei commutatori intermedi e di elaborazione del pacchetto.
Consideriamo ora cosa succede quando un utente clicca su un link.
Questa azione fa sì che il browser inizializzi una connessione TCP con il server web. Ciò comporta un handshake a tre vie: il client invia un piccolo segmento TCP al server, quest’ultimo lo conferma e risponde con un piccolo segmento TCP.
Infine, il client dà una conferma di ritorno al server.
Le prime due parti dell’handshake a tre vie richiedono RTT. Dopo il loro completamento, il client invia un messaggio di richiesta HTTP combinato con la terza parte dell’handshake (la conferma di avvenuta ricezione, o acknowledgement) nella connessione TCP.
Quando il messaggio di richiesta arriva al server, quest’ultimo inoltra il file HTML nella connessione TCP.
La richiesta/risposta HTTP consuma un altro RTT. Pertanto il tempo di risposta totale è, approssimativamente, di due RTT più il tempo di trasmissione da parte del server del file HTML.
HTTP con connessioni persistenti
Le connessioni persistenti presentano alcuni limiti: il primo è che per ogni oggetto richiesto occorre stabilire e mantenere una nuova connessione.
Per ciascuna di queste connessioni, si devono allocare buffer TCP e mantenere variabili TCP sia nel client sia nel server.
Questo pone un grave onere sul server web, che può dover servire contemporaneamente richieste provenienti da centinaia di diversi client.
In secondo luogo, come abbiamo appena descritto, ciascun oggetto subisce un ritardo di consegna di due RTT, uno per stabilire la connessione TCP e uno per richiedere e ricevere un oggetto.
Nelle connessioni persistenti, il server lascia la connessione TCP aperta dopo l’invio di una risposta, per cui le richieste e le risposte successive tra gli stessi client e server possono essere trasmesse sulla stessa connessione.
In particolare, non solo il server può inviare un’intera pagina web su una sola connessione TCP permanente, ma può anche spedire allo stesso client più pagine web.
Queste richieste di oggetti possono essere effettuate una di seguito all’altra senza aspettare le risposte delle richieste pendenti (pipelining).
In generale , il server HTTP chiude la connessione quando questa rimane inattiva per un dato lasso di tempo (intervallo di timeout).
Quando il server riceve richieste back-to-bak, invia gli oggetti con la stessa modalità. Il modo di default di HTTP impiega connessioni persistenti con pipelining.