[successivo] [precedente] [inizio] [fine] [indice generale]
La programmazione di rete si occupa della realizzazione di programmi che vengono eseguiti su macchine diverse e devono comunicare attraverso la rete.
Il problema può quindi essere visto come la generalizzazione di quello della comunicazione tra processi (IPC Inter Process Comunication) in cui i processi sono eseguiti su una stessa macchina.
Esistono vari modelli di architettura per le applicazioni di rete; i più importanti sono:
Il modello a tre livelli è molto interessante ma in un contesto diverso da quello preso in esame in queste dispense e cioè nel campo della realizzazione di applicazioni basate sul Web; quindi non viene approfondito in questa sede.
Il modello paritetico ha acquisito importanza e notorietà grazie alla diffusione dei servizi di condivisione di file tra nodi paritetici in Internet.
Il modello più importante in ambito GNU/Linux e, storicamente in Unix, è però quello cliente/ servente sul quale si sofferma in modo particolare il presente documento.
Lo scenario considerato è quello di comunicazioni in rete basate su protocolli orientati alla connessione (TCP) dove un cliente invia richieste di connessione a un servente che è in attesa di tali richieste.
Comunque anche le comunicazioni basate su protocolli non orientati alla connessione (UDP) vengono esaminati anche se più brevemente.
Questo paragrafo contiene una breve illustrazione del funzionamento del protocollo TCP, in particolare riguardo i meccanismi di attivazione e rilascio di una connessione.
La trattazione non ha la minima pretesa di essere esaustiva; per conoscere più in profondità questo argomento, e in generale tutto ciò che riguarda il software di rete, si consiglia la consultazione di testi specializzati come «Reti di calcolatori» di A.S. Tanenbaum. |
Nella figura 1.1 è riportato il formato del segmento TCP.
|
Segue una breve descrizione delle funzioni dei vari campi:
porta del mittente e porta del destinatario: sono le porte che identificano gli estremi della connessione a livello di trasporto; la connessione è comunque completamente identificata indicando anche l'indirizzo IP dei due nodi, quindi da due coppie di valori IP:porta;
sequence number: numero d'ordine del primo byte contenuto nel campo dati;
acknowledgement number: numero d'ordine del prossimo byte atteso;
header length: numero di parole di 32 bit presenti nell'intestazione; tale numero può variare perché il campo opzioni è di dimensione variabile;
URG: è un bit e vale 1 se è usato il campo urgent pointer, 0 altrimenti;
ACK: è un bit e vale 1 se acknowledgement number è valido, 0 altrimenti;
PSH: è un bit e vale 1 se dati urgenti (pushed data), da consegnare senza aspettare il riempimento del buffer;
RST: è un bit e vale 1 se viene richiesto il reset della connessione a seguito di qualche problema;
SYN: è un bit e vale 1 in fase di attivazione della connessione;
FIN: è un bit e vale 1 in fase di rilascio della connessione;
window size: dimensione in byte della finestra di spedizione usata per il controllo di flusso di tipo sliding window go-back-n; in pratica questo campo indica quanti byte possono essere spediti a partire da quello confermato con acknowledgement number; un valore zero indica al nodo mittente di interrompere la trasmissione e riprenderla quando riceve un segmento con stesso acknowledgement number e window size diversa da zero;
checksum: serve per un controllo di correttezza sul segmento inviato includendo però anche una pseudointestazione contenente gli indirizzi IP; questo permette al ricevente di individuare i pacchetti consegnati in modo errato ma è una violazione della gerarchia dei protocolli in quanto gli indirizzi IP appartengono al livello rete e non a quello di trasporto dove «risiede» il TCP;
urgent pointer: puntatore ai dati urgenti;
opzioni: vengono negoziate all'attivazione della connessione; le più importanti sono: dimensione massima dei segmenti da spedire, uso di selective repeat invece che go-back-n, uso di segmenti NAK;
La connessione TCP tra due nodi di rete viene attivata con il meccanismo TWH (Three Way Handshake).
Uno dei due nodi, il servente, esegue le funzioni listen() e accept() e rimane in attesa di una richiesta di connessione su una certa porta; l'altro nodo, il cliente, esegue la funzione connect() indicando l'indirizzo IP e la porta del servente.
Questo causa l'invio di un segmento TCP col bit SYN a uno, il bit ACK a zero e un numero di sequenza creato al momento con un meccanismo basato sul clock di sistema.
All'arrivo di tale segmento l'entità a livello di transporto del servente controlla se c'è un processo in ascolto sulla porta specificata:
in caso negativo invia una risposta col bit RST a uno, in modo da rifiutare la connessione;
in caso positivo e se il processo accetta la connessione, viene inviato un segmento di conferma, con bit ACK a uno; in tale segmento però anche il bit SYN vine posto a uno e viene generato un altro numero di sequenza, affinché anche il servente chieda conferma della connessione al cliente.
Se anche quest'ultimo accetta la connessione invia una risposta con bit ACK a uno al servente e l'attivazione si conclude con successo; da questo momento i due nodi possono iniziare a scambiarsi segmenti dati.
Nella figura 1.2 è schematizzato il meccanismo di attivazione di una connessione TCP.
|
Per il rilascio, la connessione, che è full-duplex, viene considerata come una coppia di connessioni simplex indipendenti.
Il meccanismo (stavolta a «quattro vie») è il seguente:
uno dei due nodi invia un segmento con bit FIN a uno;
se l'altro nodo conferma con un segmento con ACK a uno, la connessione in uscita dal primo nodo viene rilasciata;
anche l'altro nodo esegue lo stesso procedimento e rilascia la connessione nell'altra direzione.
Anche in questo caso i passi del procedimento possono diventare tre se il secondo nodo invia in un solo segmento l'ACK e il suo FIN al primo nodo.
Nella figura 1.3 è schematizzato il meccanismo di rilascio di una connessione TCP.
|
Per evitare il problema noto in letteratura tecnica come «problema dei 2 eserciti» vengono usati dei contatori di tempo.
Il problema dei due eserciti consiste in due eserciti alleati che devono attaccare insieme, pena la sconfitta, un esercito nemico e quindi devono sincronizzare le proprie azioni con l'invio di messaggeri che però possono essere catturati o uccisi; è una situazione molto simile a quella dei due nodi di rete che devono sincronizzarsi per rilasciare la connessione correttamente e si inviano dei messaggi che possono andare persi.
Il problema, che non ha una soluzione teoricamente perfetta, viene affrontato, in modo comunque efficace nella pratica con l'uso di temporizzatori: se una risposta a un FIN non arriva entro un certo tempo, il mittente del FIN chiude la connessione; l'altro nodo va in timeout perché si accorge che nessuno sembra ascoltarlo più.
I processi serventi in rete possono essere di due tipi diversi:
iterativi: rispondono alle richieste di servizio e restano occupati fini al loro completamento, al termine ritornano disponibili per altre richieste;
concorrenti: gestiscono le richieste creando processi figli, incaricati di rispondere, e ponendosi immediatamente ancora in ascolto di altre richieste; i processi figli terminano una volta esaurito il loro compito.
Le interfacce software o API (Application Program Interface) di comunicazione più utilizzate fra processi in rete, sono:
socket di Berkeley, di Unix BSD;
TLI (Transport Layer Interface) di Unix System V.
Entrambe sono definite per il linguaggio C e fra le due la API basata sui socket è senz'altro la più usabile e flessibile e quindi la più diffusa; essa è stata introdotta nel 1982 in Unix BSD 4.1c ed è rimasta sostanzialmente invariata.
I socket vengano usati per la comunicazione di rete in molti sistemi operativi, compresi Unix e GNU/Linux e possono essere utilizzati anche per far comunicare processi in esecuzione sulla stessa macchina.
La flessibilità dei socket permette di usarli a fronte di stili di comunicazione diversi: ad esempio nel caso di invio dei dati come flusso di byte o suddivisi in pacchetti, di comunicazioni affidabili o non affidabili, di comunicazioni punto a punto o broadcast e altro ancora.
Nel caso di comunicazione in rete i socket possono essere usati con protocolli diversi; come già detto però in queste dispense si fa riferimento unicamente all'uso dei socket con l'architettura TCP/IP (protocolli TCP e UDP).
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome il_software_di_rete.html