18.4 Comunicazione tra client e server

Come illustrato in cap. 16, la comunicazione di rete avviene tra due processi detti client e server. In particolare il server attende una richiesta da parte di un client e risponde alla richiesta stessa. In questa sezione viene esaminato più in dettaglio la procedura di comunicazione tra client e server per i protocolli a livello di trasporto.

L’interfaccia software più utilizzata per la scrittura di programmi di comunicazione è quella che si rifà ai socket di BSD (v. sez. 7.6.4). Tale interfaccia di programmazione permette la comunicazione tra due processi, sia sulla stessa macchina che su macchine diverse, utilizzando per default lo stack di protocolli TCP/IP. Dal punto di vista della programmazione, lavorare con i socket è analogo a lavorare con i file.

Il server deve innanzitutto deve riservare un socket relativo ad un indirizzo IP ed a una porta ed indica il tipo di protocollo da utilizzare nella comunicazione. Le porte riservate per servizi standard, sono dette well known port numbers e sono riportate dalla RFC 1060 (ad esempio, la porta 80 è quella standard dei server HTTP, la porta 25 è quella standard dei server SMTP, ...). Il file /etc/services riporta un elenco delle porte associate ai vari servizi.

Per server relativi a servizi non standard è buona regola utilizzare un numero di porta che non è elencato fra quelli associati ai servizi standard.

Dunque, il server rimane in attesa di una richiesta da parte di un client, richiedendo al sistema operativo di mettergli a disposizione un buffer nel quale verranno accodate al massimo un determinato numero di richieste ricevute.

Non appena il server riceve una richiesta da parte di un client, questo procede alla sua elaborazione fino a fornire una risposta al client stesso. Mentre il server è occupato nell’elaborazione della richiesta e nella preparazione della relativa risposta, potrebbero arrivare altre richieste da parte di altri client. Tali richieste saranno memorizzate dal sistema operativo nel buffer precedentemente riservato a tale scopo, fino ad un massimo indicato dal server. Le richieste che eccederanno tale valore saranno automaticamente scartate.

Per ovviare al problema della possibile perdita delle richieste che arrivano durante l’asservimento di un’altra richiesta, si utilizza in genere la tecnica di affidare la gestione della comunicazione con un client ad un processo o thread a parte. In questo modo il processo (o thread) principale che riceve una richiesta da parte di un client crea il processo (o thread) figlio facendo gestire ad esso l’elaborazione della richiesta e la generazione della relativa risposta, ed esso ritorna subito in ascolto di altre eventuali richieste da parte dei client.

Quindi il server invia la risposta al client e ritorna in attesa di ulteriori richieste (se ci sono delle richieste pendenti, queste sono viste dal server come ulteriori richieste) da elaborare.

Il client invece deve inizialmente riservare un socket in relazione soltanto ad un indirizzo IP ed al protocollo utilizzato nella comunicazione, mentre il numero di porta non è indispensabile, ma viene generalmente lasciato decidere al sistema operativo, che ne sceglierà uno opportuno non riservato e non già utilizzato. Quindi, si connette al server specificando il relativo indirizzo IP e numero di porta (è necessario che il client conosca il numero di porta relativo al server).

Quindi, procede all’inivio di una richiesta al server e si mette in attesa di una risposta da parte dello stesso.

Al termine delle operazioni può chiudere l’eventuale connessione precedentemente aperta.


pict
Figura 18.5: Schematizzazione di un’applicazione server.


pict
Figura 18.6: Schematizzazione di un’applicazione client.

[da completare ...]