Funzionamento dei socket per la gestione della connessione

In questa lezione esploreremo il funzionamento dei socket, componenti fondamentali per la comunicazione tra processi in rete nel contesto delle architetture client-server.

Analizzeremo come i socket permettano di instaurare, gestire e chiudere le connessioni, pilastri essenziali per comprendere i servizi web moderni e le reti distribuite.

  • shape
  • shape


Funzionamento dei socket per la gestione della connessione

Quando uno studente clicca su un link e la pagina compare quasi subito, l'impressione e che sia avvenuta una cosa sola. In realta ne sono avvenute tre, e in un ordine preciso: e stata aperta una comunicazione fra il suo dispositivo e il server, sono stati scambiati dei dati, e la comunicazione e stata chiusa. Capire queste tre fasi, e cosa accade in ciascuna, e il passo che trasforma il socket da definizione astratta in strumento comprensibile.

Nella lezione precedente abbiamo visto che cos'e un socket e come viene identificato. Qui vediamo come i due capi lo usano per costruire, mantenere e chiudere una comunicazione, concentrandoci sul caso piu strutturato, quello delle comunicazioni orientate alla connessione.

Le tre fasi di una comunicazione

Una comunicazione orientata alla connessione attraversa sempre le stesse tre fasi. Nella prima, l'apertura, i due capi stabiliscono un collegamento logico: si riconoscono e si mettono d'accordo sul fatto che d'ora in poi staranno parlando fra loro. Nella seconda, lo scambio dei dati, le informazioni viaggiano nei due sensi lungo quel collegamento. Nella terza, la chiusura, il collegamento viene sciolto e le risorse impegnate vengono liberate.

La distinzione fra le tre fasi non e una formalita: in ciascuna possono presentarsi problemi diversi, e un programma ben scritto li tratta in modo diverso. Non riuscire ad aprire una comunicazione, perdere il collegamento a meta di uno scambio o non chiuderlo correttamente sono tre guasti distinti, con conseguenze distinte.

L'apertura: ascolto, richiesta e accettazione

L'apertura non e simmetrica, perche i due ruoli fanno cose diverse. Il server, come visto, ha gia un socket associato alla porta del servizio e messo in ascolto: e pronto a ricevere tentativi di contatto, ma non sta parlando con nessuno. Il client, dal suo lato, avvia una richiesta di connessione verso l'indirizzo e la porta del server.

Quando la richiesta arriva, il server la accetta, e qui accade il passaggio piu importante da capire: il socket in ascolto non diventa il canale di comunicazione con quel client, ma resta libero di accogliere altri arrivi. Per il client appena accettato viene invece creato un capo di comunicazione dedicato, distinto dal primo. E per questo che un server puo servire molti client insieme senza che le loro comunicazioni si mescolino, come gia osservato parlando della coppia di socket che identifica ogni comunicazione.

Il meccanismo somiglia al centralino di una scuola. Il numero pubblicato sul sito e sempre lo stesso e resta sempre libero di ricevere nuove chiamate: e il socket in ascolto. Quando una chiamata viene accettata, la conversazione prosegue su una linea interna dedicata a quella persona, mentre il numero principale torna subito disponibile per chi chiamera dopo.

Lo scambio dei dati

Una volta aperta la comunicazione, il collegamento e bidirezionale: entrambi i capi possono scrivere e leggere, non esiste un verso privilegiato imposto dal socket. Cio che viaggia e un flusso di byte, che il socket consegna nell'ordine in cui e stato inviato, senza pero attribuirgli alcun significato.

Chi parla, quando, e che cosa ci si aspetta come risposta non lo decide quindi il socket, ma il protocollo applicativo, come visto nella lezione dedicata. E una divisione dei compiti netta e vale la pena tenerla a mente: il socket garantisce che i byte scritti da un capo arrivino all'altro, il protocollo stabilisce che quei byte vadano interpretati, per esempio, come la richiesta di una pagina o come un messaggio di posta.

Regola fondamentale: una connessione non e un cavo riservato ai due programmi, ne un collegamento fisico dedicato. E uno stato condiviso, mantenuto dai due capi finche entrambi lo tengono aperto, mentre i dati viaggiano su una rete usata contemporaneamente da moltissime altre comunicazioni.

La chiusura e il rilascio delle risorse

Terminato lo scambio, la comunicazione va chiusa. La chiusura ordinata serve a due cose: comunicare all'altro capo che non arriveranno altri dati, cosi che non resti in attesa inutilmente, e liberare le risorse che il sistema operativo aveva riservato a quella comunicazione.

Quest'ultimo punto ha conseguenze pratiche importanti dal lato server. Ogni comunicazione aperta occupa memoria e un capo di comunicazione: un server che accetta connessioni senza mai chiuderle correttamente accumula risorse impegnate inutilmente, fino a non poterne accettare di nuove. E uno dei modi concreti in cui si manifesta il problema della capacita di gestire piu richieste in concorrenza, visto parlando delle caratteristiche del server: non basta accettare i client, bisogna anche congedarli.

Nel laboratorio scolastico, uno studente che chiude il browser fa terminare la propria comunicazione con il server didattico, che libera le risorse dedicate a lui; il servizio resta perfettamente attivo per gli altri diciannove, perche il socket in ascolto non era mai stato impegnato in quella conversazione.

Errori comuni e limiti

Il primo errore e immaginare la connessione come un canale fisico riservato, una specie di filo diretto fra i due programmi. Non esiste nulla del genere: la rete e condivisa, e la connessione e solo l'accordo fra i due capi sul fatto di essere in comunicazione. Da questo equivoco nasce l'idea sbagliata che aprire tante connessioni "occupi la rete" allo stesso modo in cui occuperebbe tanti cavi.

Il secondo errore, molto piu frequente nella pratica della programmazione, e trascurare la chiusura. Un programma che dimentica di chiudere le comunicazioni funziona benissimo nelle prove con pochi utenti e si comporta male nella realta, quando le comunicazioni sono migliaia: e un guasto che si manifesta solo sotto carico, ed e per questo che si scopre tardi.

Un terzo equivoco riguarda il significato di connessione stabilita. Sapere che l'apertura e riuscita dice che il programma dall'altra parte era in ascolto e ha accettato, non che stia funzionando correttamente o che sara in grado di rispondere. Una comunicazione puo essere perfettamente aperta e restare comunque senza risposta utile, per ragioni che riguardano l'applicazione e non il collegamento.

Sintesi applicativa

Ragionare su una comunicazione di rete significa chiedersi, nell'ordine: l'apertura e riuscita, cioe dall'altra parte c'era qualcuno in ascolto che ha accettato? Lo scambio sta avvenendo secondo le regole del protocollo previsto? La chiusura avviene e le risorse vengono liberate? Le tre domande corrispondono alle tre fasi e individuano problemi di natura diversa. Nella prossima lezione vedremo con quali operazioni concrete, chiamate primitive, un programma realizza ciascuna di queste fasi.

Domanda di autoverifica: un server accetta regolarmente nuovi client per alcune ore, poi comincia a rifiutare qualunque nuovo collegamento pur non essendo spento e pur avendo processore e memoria apparentemente liberi. Quale delle tre fasi viste in questa lezione conviene sospettare per prima, e perche?

Paragrafi letti

 

    
0%
       Salva

Statistics