CHAT TCP - Gabriele-Farinella-Peano-5A/ChatTCP GitHub Wiki
FUNZIONAMENTO CHAT TCP
La chat TCP è composta da:
- Server: è sempre in ascolto, riceve messaggi dai vari client connessi e li inoltra a tutti.
- Client: una volta inviato il messaggio al server si mette in ascolto.
Il protocollo TCP (Trasmission Control Protocol) è molto più AFFIDABILE rispetto al protocollo UDP però il flusso di dati è più grande e quindi è più lento.
SERVER
Il progetto serverTCP è composto da 3 classi: serverTCP, MessageManager e socketWorker
La classe MessageManager salva l'ultimo messaggio ricevuto e lo invia a tutti i socketWorkers che lo inviano a loro volta a tutti i Client attraverso:
synchronized void sendNewMessaggio(String m) { //aggiorna l'ultimo messaggio nella variabile dell'oggetto this.messaggio = m; //chiedi ad ogni worker di inviare il messaggio ricevuto for (SocketWorker worker: this.workers) { worker.sendMessaggio(this.messaggio); }
La classe socketWorker rappresenta il "Lavoratore" di ogni client e gestisce la connessione tra il Client e il server, in questa classe vengono usati i Thread.
Qui viene creata la connessione con il socket per ricevere ed inviare il testo
BufferedReader in = null; try{ // connessione con il socket per ricevere (in) e inviare(out) il testo // da/al client connesso in = new BufferedReader(new InputStreamReader(client.getInputStream())); out = new PrintWriter(client.getOutputStream(), true); } catch (IOException e) { System.out.println("Errore: in|out fallito"); System.exit(-1); }
Qui il socket viene messo in attesa di ricevere un messaggio in input e una volta ricevuto lo invia al Server.
//mi metto in attesa di ricevere un nuovo messaggio da client line = in.readLine(); //il nuovo messaggio e' stato ricevuto e lo andiamo ad inserire //nella variabile "messaggio" della classe EventoReceiver //il quale aggiornera' la variabile e richiedera' l'invio a ogni //Worker, ognuno al proprio client messaggioReceived(line); //scrivi messaggio ricevuto su terminale System.out.println(clientPort + ">> " + line); } catch (IOException e) { System.out.println("lettura da socket fallito"); System.exit(-1);
La classe chatTCP è la classe principale del progetto ed è la classe in cui:
Viene dichiarata la porta del Server:
int portNumber = 1234; //porta a cui il server si mettera' in ascolto
Il server viene messo in ascolto e attende di connettersi con il Client, successivamente viene generato un Thread e viene avviato il worker del Client che si è connesso nel Thread:
try{ //metto il server in ascolto alla porta desiderata per clients che //richiedono connessione ServerSocket server = new ServerSocket(portNumber); System.out.println("Server chatTCP in esecuzione...");
while(true){
//Socket Worker e' l'oggetto che si occupa di servire il client
//che si e' connesso, ne verra' generato un Worker per ogni
//client e verra' eseguito in un suo Thread personale
SocketWorker w;
try {
//mi metto in attesa di una nuova richiesta di connessione
//server.accept() restituisce il nuovo socket
Socket newSocket = server.accept();
//una nuova connessione con un nuovo client e' stata creata
//creo un nuovo "servitore"(SocketWorker) che si prendera'
//cura del nuovo client
w = new SocketWorker(newSocket);
//genero il Thread per l'esecuzione del nuovo Worker
Thread t = new Thread(w);
//Avvio l'esecuzione del nuovo worker nel Thread
t.start();
} catch (IOException e) {
System.out.println("Connessione NON riuscita con client: ");
System.exit(-1);
}
}
} catch (IOException e) {
System.out.println("Error! Porta: " + portNumber + " non disponibile");
System.exit(-1);
}
CLIENT
Il progetto clientTCP è composto da 2 classi: clientTCP e Listener
La classe Listener permette al client una volta inviato un messaggio di mettersi in ascolto per ricevere messaggi che potrebbero arrivare da altri Client o dal Server
// connetti al socket per poter leggere i dati che arrivano al Client // (client <-- server) BufferedReader in = null; try{ in = new BufferedReader(new InputStreamReader(client.getInputStream())); } catch (IOException e) { System.out.println("IO Error!!!"); System.exit(-1); }
//scrivi su terminale il testo ricevuto
String testoDaServer = "";
try {
while ((testoDaServer = in.readLine()) != null) {
System.out.println(testoDaServer);
La classe clientTCP è la classe principale del progetto e permette al Client di connettersi al Server usando i Socket, di mettersi in ascolto attraverso i Thread e di inviare messaggi al server.
Vengono dichiarati indirizzo IP e porta:
String hostName = "127.0.0.1"; int portNumber = 1234;
Viene creato un socket e gli vengono assegnati indirizzo IP e porta:
// prendi l'indirizzo IP del server dalla linea di comando InetAddress address = InetAddress.getByName(hostName);
// creazione socket
Socket clientSocket = new Socket(address, portNumber);
Viene effettuata una connessione concorrente al socket e una volta che il testo da linea di comando viene acquisito viene inviato al Server:
Listener l; try { l = new Listener(clientSocket); Thread t = new Thread(l); t.start(); } catch (Exception e) { System.out.println("Connessione NON riuscita con server: "); }
// connessione al socket (in uscita client --> server)
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
// connessione allo StdIn per inserire il testo dalla linea di comando
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
//leggi da linea di comando il testo da spedire al Server
System.out.print(">"); //visualizza il prompt
while ((userInput = stdIn.readLine()) != null) {
// scrittura del messaggio da spedire nel socket
out.println(userInput);
System.out.println("Messaggio spedito al server: " + userInput);
System.out.print(">"); //visualizza il prompt
}