Computer Network Lesson

LEZIONE del 2 Dicembre

I problemi che devono essere affrontati nella realizzazione di programmi la cui esecuzione viene effettuata all'interno di un sistema a risorse distribuite presentano caratteristiche peculiari che si possono riassumere nell'identificazione e localizzazione delle risorse necessarie per la sua effettiva esecuzione.

Si tenga presente che, in molti casi, il programma è parallelo a tutti gli effetti, nel senso che l'esecuzione è ottenuta lanciando le sue componenti sequenziali su uno o più nodi della rete ed, inoltre, deve essere stato previsto uno specifico protocollo per lo scambio di informazioni fra le varie componenti sequenziali.

Si rammenta, a questo proposito, che tali componenti hanno la struttura tipica dei server, ossia, sono programmi continuamente attivi sulla rete perchè contribuiscono a fornire i servizi cui il programma parallelo è destinato. Nel caso più semplice lo schema è quello di un unico programma server che fornisce un certo servizio mentre è in esecuzione su nodo noto della rete a tutti i processi clienti che ne fanno richiesta.

Lo schema multi-client/single-server in modalità connessa è il più semplice da realizzare. La figura riportata di seguito

Schema client-server

ne illustra chiaramente la struttura. La realizzazione è quella standard per la rete Internet.

L'implementazione mediante socket è quella che si può dedurre nel caso esemplificato del servizio fornito da un certo server, che è quello di listare il contenuto di un direttorio, passato come parametro, della macchina su cui il server è in esecuzione.

Il cliente chiederà al server di listare il contenuto di un direttorio ed è stato realizzato per connettersi su una specifica macchina oppure su quella passata come parametro nella fase di inizio di esecuzione del cliente.

Per compilare i due programmi è necessario eseguire i comandi

gcc -lnsl -lsocket -o client client.c
gcc -lnsl -lsocket -o server server.c readdir.c
e trasferire l'eseguibile server sulla macchina scelta, secondo quanto indicato nella variabile HOST del client.

A questo punto lanciare l'esecuzione col comando

server &

Si noti nel codice del server la presenza della chiamata setsockopt con lo scopo di definire opportunamente alcune opzioni nella gestione della socket. Nel caso specifico i parametri passati servono a permettere il riutilizzo dell'indirizzo assegnato dalla bind per chiamate successive del server.

Come &grave facile rendersi conto il server termina normalmente dopo aver accettato la prima richiesta. In generale, tuttavia, i server devono essere realizzati in modo da poter rispondere ad un numero qualsivoglia di richieste provenienti dai clienti. Il secondo tipo di server soddisfa questa richiesta, nel senso che rimane sempre attivo in attesa di essere risvegliato da qualche cliente.

Per lanciare l'esecuzione di questa versione modificata di server si eseguano i comandi riportati di seguito sulla macchina prescelta per il server

gcc -lnsl -lsocket -o mserver readdir.c mserver.c
mserver &
e quindi lanciare i clienti remotamente, verificando che questi tentino la connessione sul nodo corretto. Ricordarsi di uccidere il processo mserver. Si consideri anche il caso di lanciare più server sulla stessa macchina o su macchine diverse e si cerchi di capire le eventuali modifiche da apportare al codice.

Si noti, nel codice di mserver.c, la presenza dell'istruzione signal che ha il compito di modificare la maschera delle interruzioni per il processo in modo che questo ignori il segnale di terminazione dei processi figli i quali, altrimenti, darebbero luogo a processi zombie.