Elaborato di Sistemi Operativi – Chat Java

Chat Java

Per l’esame di Sistemi Operativi ho voluto fare un elaborato in quanto mi sono accorto che era la via migliore per imparare ciò che veniva insegnato.
Credo che in generale qualsiasi esame come ogni laurea e scuola dovrebbe prevedere una parte nella quale si mette in pratica la teoria per risolvere qualche problema.
Questo aspetto è spesso sottovalutato o applicato male, ma sembra che con il tempo molte persone, indipendentemente dall’ambiente in cui si pone questo problema, stiano capendo che questa è un’ottima soluzione per unire l’utile al dilettevole.
Soprattutto quando il lavoro è fatto per aiutare anche aziende, che poi eventualmente entreranno in contatto con i nuovi lavoratori.
Questa è una filosofia impeccabile e semplice da applicare nel modo giusto.

Inizialmente la mia idea era quella di realizzare un videogioco, un PacMan multiplayer da giocare via Internet ed avevo in effetti iniziato a farlo, ma per quanto veniva insegnato nel corso di Sistemi Operativi il progetto necessitava di studiare a fondo parti del linguaggio Java in modo totalmente individuale.
Non avendo quindi queste basi avrei dovuto studiare e far pratica di Java in maniera assidua ed individuale.
Gli eventi sia universitari che di lavoro hanno poi fatto spostare questo esame più in là nel tempo, finché non mi sono ritrovato a dover fare il corso di Tecnologie del Software per Internet in relazione al modulo professionalizzante riguardo la programmazione di apllicazioni per il web.
Quest’ultimo corso era in buona sostanza quasi interamente basato sul Java di cui si imparava molto di più rispetto al corso di Sistemi Operativi.
Poneva quelle basi necessarie a fare quell’elaborato, diciamo esagerato, che io volevo fare per l’esame di Sistemi Operativi.
Era comunque una mia idea quella di fare un qualcosa che fosse al di là delle necessità del corso.
I normali elaborati previsti non soddisfacevano la mia voglia di fare un programma interessante.
Si potrebbe dire che da un lato mi sono tirato chiaramente la zappa sui piedi da solo, ma dall’altro, grazie alla realizzazione di questa chat in Java e dell’elaborato fatto per Tecnologie Software per Internet, io ed altri miei compagni di studio abbiamo appreso quanto bastava per iniziare a produrre qualcosa di reale, esperienza basilare per cominciare a lavorare nel campo.
Con gli altri elaborati più semplici  e consoni avrei imparato molto meno.
Dipende tutto da cosa si vuole fare. Io ho fatto del lavoro in più per un esame che avrei passato lo stesso, ma questo lavoro in più mi è utile tuttora come curriculum e come lavoro nel caso qualcuno mi richieda di scrivere un programma in Java.

In un primo tempo non abbandonai il progetto di realizzare il PacMan Multiplayer in Java.
In realtà lo volevo fare, ma siccome in un solo mese mi accingevo alla mitica impresa di effettuare sette esami insieme, il tempo tendeva a zero.
E va detto all’onor del vero, che quella volta studiai anche per le feste, tutte: Natale, l’ultimo dell’anno, il primo dell’anno…
Per l’appunto, durante il laboratorio di Tecnologie Software per Internet mi misi a fare una chat in Java per mettere in pratica tutto ciò che stavo leggendo sulle fotocopie di Java inerenti al corso.
Arrivato così a un certo punto realizzai che se al professore fosse andato bene come elaborato quella chat in Java che era già semi-realizzata potevo risparmiare del tempo e unire l’utile al dilettevole, ovvero avevo fatto pratica e imparato il Java per un esame e allo stesso tempo avevo realizzato il lavoro che  se proseguito mi consentiva di passare anche un altro esame. In quanto gli argomenti dell’uno e dell’altro erano legati.
Di fatti gli argomenti centrali di Sistemi Operativi riguardo il Java erano l’applicazione dei concetti di processo, thread e sincronizzazione degli stessi, oltre alla loro comunicazione su macchine diverse tramite sockets.
Questi argomenti erano presenti anche nel corso di Tecnologie Software per Internet.
Proposi così al professore di poter finire la chat in Java e di presentarla al suo esame di Sistemi Operativi.
Il professore accettò e io mi misi di buona lena per terminare la chat, almeno in quegli aspetti che bastavano per passare l’esame di Sistemi Operativi.
Sì, perché in realtà, dal mio punto di vista la chat non è, e non era completa, ma comunque le funzioni base c’erano e in linea di massima funziona e questo era l’importante.
D’altronde ero già ampiamente sopra ciò che bisognava fare per passare l’esame e stavo già perdendo un sacco di tempo rispetto al resto del programma del corso di Sistemi Operativi. Infatti quando mi sono presentato all’esame ho ammesso di aver trascurato troppo il resto del programma d’esame per l’elaborato.

La chat da me realizzata in buona sostanza è una applicazione Java, un programma in Java che serve a chattare con altre persone a distanza.
Ogni persona usa lo stesso programma. Ponendo che vi siano 3 persone con macchine diverse sparse per il mondo, una in Italia, una a Barcellona ed una a Praga.
Se l’italiano vuole fare da server gli altri si connetteranno a lui e potranno comunicare tra loro.
Effettuare una chat significa chiacchierare attraverso Internet e quindi scambiarsi dei messaggi.
La chat comprende un luogo, una stanza nella quale alcune persone si ritrovano e parlano.
Ogni messaggio di ogni persona è quindi ricevuto da tutte le altre.
Questo programma infatti può fare sia da server che da client.
Il server è chi oltre che a chattare riceve i messaggi di tutti gli altri e li spedisce al tutti gli altri.
Il server è il sistema centrale. Il client si connette al server e manda i suoi messaggi. Sarà il server una volta ricevuto il messaggio del client X a rimandarlo a tutti i clients compreso chi lo ha mandato. Così infatti funziona anche il mio programma. Questo meccanismo è instaurato per far sì che i messaggi che compaiono sulla nostra finestra siano in linea di massima i messaggi che compaiono anche sulle finestre degli altri. Infatti potrebbe succedere che noi scriviamo un messaggio sulla finestra ma che al server non arriva e quindi nemmeno agli altri. Così invece abbiamo una prima conferma che il messaggio almeno al server è arrivato.

Se si vuole fare il server, l’applicazione ottiene automaticamente tramite le funzioni Java l’IP della macchina sulla quale sta girando. Si può quindi scegliere una porta sul quale far partire il server. I clients a questo punto dovranno immettere negli appositi spazi l’IP e la porta del server. Vi sono dei pulsanti per far partire e fermare il server e per far connettere e disconnettere il client. Sia il client che il server hanno sia il pannello di configurazione sia il pannello di chat. Nel pannello di chat vi è semplicemente una textarea dove compaiono i messaggi e poi un textfield dove inserire il proprio messaggio e un pulsante per spedirlo.
L’area di status indica alcuni messaggi del tipo se ci siamo connessi o meno ad un server o se siamo un server, se esso è partito e quali utenti si sono connessi.

Dal punto di vista della programmazione si può dire che il programma è diviso semplicemente in tre packages, uno generale, uno per le azioni corrispondenti ai pulsanti e uno per le classi che gestiscono i vari socket.

In breve possiamo dire che l’applicazione è rappresentata da ChatA2.java e qui apro un’altra parentesi. Infatti l’applicazione si chiama proprio ChatA2. Questo nome fu inventato in quanto per esperimento volevo fare prima una chat per solo due persone senza usare il meccanismo dei threads e poi una chat per N persone con i thread. In realtà è stato utilissimo fare questa esperienza in quanto via via procedendo di code and fix mi sono accorto che i thread dovevo usarli comunque proprio perchè stavo mettendo su una interfaccia grafica (GUI). Così il nome è rimasto ChatA2 ma io ed il mio compagno di studi, che si era unito a me nello sviluppo dell’applicazione per fare esperienza insieme, ci siamo accorti che valeva tanto realizzare direttamente una chat multithread.

ChatA2.java è il file principale con tanto di main che genera un nuovo thread quello relativo a ChatA2app ovvero la nostra applicazione. Questo ultimo file ha il compito di generare l’interfaccia grafica e di controllarla assegnando le azioni relative ai due pulsanti principali che sono quello per connettersi al server che ha ConnectServerAction e DisconnectServerAction per gestire le procedure da fare sia nel caso ci si connetta che ci si disconnetta dal server e così via il pulsante Start Server ha StartServerAction e StopServerAction.

Sostanzialmente quando si preme il bottone StartServer si fa partire un Server Socket sul nostro IP con la porta scelta e poi si passa il tutto ad un nuovo thread chiamato SocketManager. Esso si mette in ascolto tramite il socket e ad ogni richiesta di connessione da parte di un client genera un nuovo socket per il client e un nuovo thread per gestirlo chiamato clientUserSocket. Ogni clientUserSocket si occupa di gestire il socket e i relativi input e output stream appartententi in relazione a un singolo client. Quindi ogni client ha un suo socket sul server gestito da un thread apposito.

Dall’altra parte quando si preme Connect Server ci si connette al server sulla porta e sull’ip stabilito nel pannello di configurazione, il tutto tramite la ConnectServerAction che genera un nuovo socket sul client e lo passa un thread che lo gestisce ClientSocketManager, questo provvederà a gestire input e output stream.

A questo punto va detto che la chat, l’area di testo, textarea viene acceduta tramite un oggetto chiamato ChatWriter. Inoltre vi è un altro oggetto chiamato ConfigurationState che contiene indicazioni sullo stato dell’applicazione cioè se è server o client, se è connessa o meno.

Inoltre va detto che il server tiene l’elenco degli utenti in un vettore Vector Java e in base ad esso il server fa riferimento al thread, al socket e agli inputstream e outputstream di ogni client.

Ogni volta che un client si connette viene aggiunto un chatter al vettore con tutte le informazioni relative per l’appunto il suo thread che lo gestisce, il suo socket e i suoi input e output stream.

Quando scriviamo un messaggio, che sia client o server andiamo a mandarlo tramite la SendMsgAction al ChatWriter che ha un apposito metodo per scriverlo, questo metodo individua se si è server o client attraverso l’apposito oggetto ConfigurationState e verifica se veramente siamo connessi. A questo punto se si è un server lo scrive sulla propria textarea di chat e scorre il vector dei chatters per mandarlo ad ogni utente tramite il socket e tramite quindi l’outputstream.

Se invece siamo in modalità client, il messaggio viene passato al socket gestito da ClientSocketManager, in outputstream. Il server lo riceve tramite il thread apposito sempre sul socket e richiama a sua volta il chatwriter che lo manda a tutti i client. A questo punto il client riceve il messaggio tramite il ClientSocketManager.

Il ClientSocketManager è il thread che gestisce il socket sull’applicazione che fa da client e resta quindi in ascolto, ad ogni messaggio lo manda al chatwriter che lo manda alla textarea della chat.

Il server ha un clientUserSocket per ogni utente. Ognuno fa restare in ascolto il suo socket e nel momento in cui arriva un messaggio richiama il chatwritter per mandarlo a tutti gli utenti.

Capite bene che sul server quindi il chatwriter potrebbe essere interpellato da N utenti contemporanei tramite i loro socket gestiti dai loro userClientSocket.
Si necessita quindi di un meccanismo di sincronizzazione che in Java si può applicare tramite l’uso dello statement synchronized. Questo statement definisce che un certo metodo di un certo oggetto può essere richiamato da un solo thread alla volta e finché non è stato finito di eseguire non può essere richiamato da un altro thread che rimane in attesa del suo turno. Di conseguenza in questo caso basta aggiungere lo statement synchronized per effettuare la sincronizzazzione dei processi, dei thread su i metodi del chatwriter che servono 1) per scrivere un messaggio nella chat 2) per aggiungere un utente 3) sui metodi serverControlManager e clientControlManager.

Questi ultimi metodi servono a gestire i messaggi di controllo. Infatti stavo iniziando a prevedere che ogni messaggio scambiato fra client e server sia suddiviso in messaggi di chat e messaggi di controllo fra le due applicazioni. Quindi tutto ciò è un protocollo di comunicazione. Il protocollo della nostra chat in Java. Molto semplicemente come riportano altri esempi su Internet stavo facendo in modo che il primo byte ovvero la prima lettera di ogni messaggio scambiato indichi se un messaggio è di controllo C o di testo T. Se è di controllo, il codice di due cifre seguente indica quale procedura va richiamata. Ad esempio se il client si vuole disconnettere manda un messaggio di controllo al server C01 dove 01 dice di richiamare la procedura 01 tramite uno switch. La procedura farà chiudere al server il socket, input e output stream e il thread relativi al client e manderà prima un messaggio di conferma al client il quale a sua volta chiudera socket, inputstream, outputstrame a thread relativo.

Questo protocollo può essere applicato per fare prima di tutto queste opreazioni di controllo e di sicurezza, compresa una verifica del nickname se già presente per un altro utente. Infatti allo stato attuale ogni utente può entrare anche col nick di un altro utente già connesso e ciò non va bene anche perchè il nick fa da identificatore univoco sia a livello di programmazione che a livello logico. A livello logico significa che dal punto di vista umano due persone con lo stesso nome potrebbero essere le stesse se non abbiamo altri elementi per identificarle.

Questi meccanismi però sono stati da me solo iniziati e non terminati in quanto avevo già perso abbastanza tempo nella programmazione di questo semplice programmino che alla fin fine mi sono accorto che stava ricalcando i principi sui quali è basata la IRC Internet Relay Chat presente su Internet da anni e anni.

Sono principi e meccanismo molto comuni alle chat che vanno implementati.
Il livello che volevo raggiungere era appunto quello di implementare i meccanismi di sicurezza minimi per evitare errori minimi in fase di disconnessione dal server o di stop del server e relative ripartenze oltre ad avere una lista definita di nick univoci su ogni applicazione implementando il relativo meccanismo.

Oltre ciò si va sull’utile ma non essenziale come colori e messaggi in chat più messaggi di controllo che sono presenti su varie chat come kick, ban etc etc di utenti.

Spero che questa chat possa essere comunque utile a chi la scaricherà.
Nel file Zip vi è la cartella derivata dall’IDE Eclipse, quindi vi è tutto, file .class e file .java. Non ricordo se ho incluso anche il .jar della applicazione comunque chi capisce un minimo di Java sa come far partire il programma, ovviamente prima di tutto dovete aver installato sul vostro computer la relativa JRE per il vostro sistema operativo, dopo di che non vi resta che compilare l’applicazione o usare le classi già compilate, entrare in console, compilare o meno e lanciare il programma.

 

Ultimo aggiornamento: 18/12/2011