Skip to content

Francesco7602/Laboratorio2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Obiettivo del progetto

L'obiettivo del progetto è sviluppare un server che gestisca due tipi di connessione, permettendo ai client di interagire con un archivio.
Il server è implementato come un eseguibile Python, mentre l'archivio è un programma C eseguito come sottoprocesso dal server.

Funzionalità del server

Il server permette l'aggiunta di elementi all'archivio e l'interrogazione dello stesso.
Ogni connessione col server viene tracciata nel file server.log, e ogni interrogazione viene salvata nel file lettori.log in append.

Gestione dei segnali

Alla ricezione del segnale SIGINT, il programma scrive sullo standard error (stderr) il numero di stringhe distinte salvate nella tabella hash e non termina.
Quando riceve il segnale SIGTERM, il programma scrive sullo standard output (stdout) il numero di stringhe distinte salvate nella tabella hash e termina in modo pulito.
Il server, alla ricezione del segnale SIGINT, gestisce l'eccezione inviando il segnale SIGTERM all'archvio.

Il progetto è progettato per funzionare su ambiente Linux ed è necessario.
Per una corretta e veloce compilazione è necessario eseguire il makefile usando il comando make per creare un eseguibile dell'archvio, visto che serve al server.

Il server accetta diversi parametri:

<num_threads>: il numero massimo di thread che il server può creare per gestire le connessioni in ingresso (obbligatorio).
-r <num_readers>: il numero di thread readers creati dall'archivio (default: 3).
-w <num_writers>: il numero di thread writers creati dall'archivio (default: 3).
-v: flag per abilitare la creazione di un file di log con l'output di Valgrind (default: non presente).

Il client di tipo 1 accetta un parametro, che specifica il nome del file di input da utilizzare per l'interrogazione dell'archivio.

Il client di tipo 2 accetta almeno un parametro, che specifica i nomi dei file di input da utilizzare per l'inserimento degli elementi nella tabella hash.

Protocollo di rete

Il protocollo di rete utilizzato per la comunicazione tra il server e i client è il seguente:
Il server apre un socket TCP e si mette in attesa di connessioni, e può ricevere due tipi di connessioni:

Connessioni di tipo A

Le connessioni di tipo A servono per interrogare l'hash table.

Il client1 utilizza le connessioni di tipo A, inviando un pacchetto di connessione contenente l'identificatore 'A', seguito dalla lunghezza del messaggio e dal messaggio effettivo.
Se questo client deve inviare più righe, allora deve aprire una nuova connessione per ogni riga.
Chiude la connessione quando termina l'invio della riga.

Connessioni di tipo B

Le connessioni di tipo B servono per aggiungere elementi all'hash table.

Il client2 utilizza le connessioni di tipo B, inviando un pacchetto di connessione contenente l'identificatore 'B'.
Questo client apre una connessione per file, infatti l'identificatore viene inviato solo all'apertura della connessione, successivamente invierà solo lunghezza e messaggio. Chiude la connessione quando termina l'invio di tutti messaggi.

Esempio di utilizzo

    $ git clone git@github.com:user/progetto.git testdir
    $ cd testdir 
    $ make
    $ ./server.py 5 -r 2 -w 4 -v &  # parte il server con 5 thread che 
                                    # a sua volta fa partire archivio
    $ ./client2 file1 file2         # scrive dati su archivio
    $ ./client1 file3               # interroga archivio
    $ pkill -INT -f server.py       # invia SIGINT a server.py
                                    # che a sua volta termina archivio

Scelte implementative

-Il server ed i rispettivi due client sono fatti in Python, mentre l'archivio in c.
-Nel thread dei segnali viene usata una fprintf (anche se non async-signal-safe) dato che sigwait appena riceve un segnale smette di ascoltare e gestisce il segnale ricevuto. Si rimetterà in ascolto una volta finito di gestire il segnale precedente.
-È stata creata una struttura listaCircolare usata per far comunicare i thread consumatori con il thread produttore.
Al suo interno contiene l'array, gli indici dei consumatori e del produttore, la lock per poter scrivere/leggere dal buffer ed infine le conditional variable.
-Nella connessione i dati vengono passi nel seguente modo:
Il client invia prima il suo identificatore, che può essere la stringa A o la stringa B, successivamente la lunghezza dei dati che sta per inviare ed infine i dati veri e propri.
Tutto viene inviato sotto forma byte.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published