In aceasta lucrare de laborator vor fi
acoperite total sau partial urmatoarele probleme:
·
Diagramele UML (de cazuri de utilizare, de secvente, de colaborare, de
clase, etc.) ca suport pentru dezvoltarea sistemelor software OO
·
Evaluarea
prototipurilor sau a versiunilor anterioare ale sistemelor software OO
·
Actualizarea cerintelor
sistemelor software OO (orientate spre obiecte)
·
Actualizarea analizei
sistemelor software OO
·
Actualizarea
proiectarii sistemelor software OO
·
Actualizarea
implementarii in limbajul Java a sistemelor software OO
_________________________________________________________________
Dezvoltarea sistemelor software complexe este de obicei realizata in mai multe iteratii in care:
- sunt reluate activitatile de analiza, proiectare, implementare,
testare,
- sunt adaugate activitatile de
- evaluare a iteratiei anterioare si de
- planificare a iteratiilor ulterioare.
Rezultatele iteratiei anterioare sunt
fie o versiune a sistemului software,
fie doar un prototip al acestuia.
Evaluarea rezultatelor iteratiei anterioare
consta, printre altele, din:
- verificarea functionarii corecte a sistemului (conformitatii cu specificatiile),
- evaluarea documentatiei si a codului (analiza codului),
- evaluarea gradului in care versiunea obtinuta corespunde asteptarilor utilizatorilor.
In ceea ce priveste evaluarea sistemului de comunicatie pentru conversatie textuala, dezvoltat la lucrarea anterioara, pot fi facute, printre altele, urmatoarele observatii:
- interfata grafica este rudimentara, modul de conectare la server putand fi imbunatatit,
- utilizatorii sunt identificati pe baza numelui de utilizator de pe masina pe care ei lanseaza componentele client, in loc sa isi poata alege un nume de utilizator al sistemului de conversatie (nickname)
-
bara de defilare a zonei de text ar fi
preferabil sa fie in mod automat actualizata astfel incat sa fie vizibile
intotdeauna ultimele mesaje primite,
- utilizatorii nu au nici o informatie
despre ceilalti utilizatori prezenti in conversatie
- pe un server poate exista doar un singur
grup de utilizatori la un moment dat (alternativa ar fi posibilitatea crearii
unor “camere”, grupuri, etc.)
- nu exista posibilitatea crearii unor
canale de comunicatie private, pentru conversatia intre 2 utilizatori
- etc. (lista poate fi largita in cadrul laboratorului).
In urma acestei evaluari, sa presupunem ca s-a decis ca in iteratia urmatoare sa fie realizate urmatoarele imbunatatiri:
- posibilitatea oferita utilizatorilor de a-si alege un nume de utilizator (nickname)
-
actualizarea automata a barei de
defilare a zonei de text pentru ca ultimele mesaje primite sa fie vizibile
- difuzarea de catre server a numelor de utilizator catre toti utilizatorii si informarea de catre client a utilizatorilor despre modificarile in componenta grupului de utilizatori
Desigur, raman nerezolvate anumite posibile cerinte ale utilizatorilor, cum ar fi
- posibilitatea crearii mai multor “camere” sau grupuri pe un server
- posibilitatea crearii unor canale de comunicatie private
- etc (lista poate fi largita in cadrul laboratorului).
Actualizarea analizei OO presupune:
- actualizarea diagramei UML a cazurilor de utilizare,
- actualizarea descrierii cazurilor de utilizare
- actualizarea listei claselor principale ale sistemului
- actualizarea diagramelor UML de secventa care descriu scenariile componente ale cazurilor de utilizare
- actualizarea diagramelor UML de colaborare corespunzatoare
Varianta de nivel
inalt a diagramei de secventa pentru
scenariul conectarii unui nou client.
Varianta de
nivel inalt a diagramei de secventa pentru
scenariul deconectarii unui client.
Varianta de
nivel inalt a diagramei de secventa pentru
scenariul conversatiei intre clienti.
Actualizarea proiectarii OO presupune:
- actualizarea proiectarii interfetei grafice cu utilizatorul
- actualizarea diagramelor UML de secventa si de colaborare
- actualizarea diagramelor UML de clase
- actualizarea diagramelor UML de stari
- actualizarea diagramelor UML de activitati
Interfata grafica prezentata initial unui nou utilizator, pentru alegerea numelui in vederea conectarii, este o fereastra de dialog:
In cazul in care utilizatorul propune un nume care exista deja in lista serverului, acesta respinge inregistrarea iar clientul prezinta urmatoarea fereastra de dialog:
Presupunem urmatorul scenariu:
- primul utilizator isi alege numele isw2004,
- al doilea utilizator isi alege numele swrtc2004 (moment in care ambii utilizatori sunt informati, unul de existenta celuilalt),
- cei doi utilizatori schimba cateva mesaje,
- se conecteaza al treilea utilizator, care isi alege numele rtc2004 (moment in care primii doi utilizatori sunt informati de existenta celui de-al treilea, iar acesta de existenta celorlalti doi),
- cei trei utilizatori schimba cateva mesaje,
- utilizatorul
cu numele swrtc2004 paraseste
conversatia (moment in care ceilalti doi utilizatori sunt informati).
Continutul interfetei grafice pentru cei trei utilizatori va fi urmatorul:
- pentru utilizatorul cu numele swrtc2004:
- pentru utilizatorul cu numele isw2004:
- pentru utilizatorul cu numele rtc2004:
Diagrama de clase a clientului este urmatoarea:
Diagrama de clase a serverului este urmatoarea:
Codul sursa Java pentru clientul de chat (si fisierul pentru compilarea si lansarea clientului)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
//Source
file: ClientDeChat_v2.java import java.net.*; import java.io.*; import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Properties; /** * Client de
chat simplu - aplicatie de sine statatoare * Aplicatie grafica Swing (extinde JFrame) * care poate lansa in executie un fir nou
(implementeaza Runnable) */ public class
ClientDeChat_v2 extends JFrame implements Runnable { private
String numeUser; private
String adresaLocala; private
int portLocal; /** * Vector
de obiecte cu informatii privind ceilalti clienti */ private
static Vector altiClienti = new Vector (); /** * Flux de
intrare dinspre retea */ private
DataInputStream inRetea; /** * Zona de
text (configurata ca non-editabila) */ private
JTextArea outTextGrafic; /** * Intrare
de text (editabila) */ private
JTextField inTextGrafic; /** * Fir de
executie */ private
Thread firReceptie; /** * Socket
flux (TCP) */ private
static Socket socket; /** * Flux de
iesire catre retea */ private
DataOutputStream outRetea; private
InetAddress iaLocala; JScrollBar
baraDefilareVerticala; /** *
Initializeaza obiectul de tip ClientDeChat_v1 * @param
title Titlul ferestrei * @param
inRetea Flux de intrare dinspre
retea * @param
outRetea Flux de iesire catre retea */ public ClientDeChat_v2(String title,
InputStream inRetea,
OutputStream outRetea) { // Stabilire
titlu fereastra (JFrame)
super(); //
---------------------------------------------------------------- //
Trimiterea catre server a informatiilor privind clientul // ----------------------------------------------------------------
this.inRetea = new DataInputStream (new BufferedInputStream
(inRetea));
this.outRetea = new DataOutputStream (new BufferedOutputStream
(outRetea)); //
----------------------------------------------------------------------- //
Afisarea in consola si trimiterea catre server a info. privind clientul //
----------------------------------------------------------------------- //
Obtinerea numarului de port local portLocal
= this.socket.getLocalPort(); try { //
Obtinerea adresei locale ca obiect InetAddress
iaLocala = InetAddress.getLocalHost(); //
Obtinerea formei String a adresei locale
adresaLocala = iaLocala.getHostAddress();
System.out.println("\n Clientul are adresa " + adresaLocala
+ " si portul
" + portLocal); //
Scrierea adresei IP pe fluxul de iesire spre retea
this.outRetea.writeUTF(adresaLocala); //
Scrierea portului TCP pe fluxul de iesire spre retea
this.outRetea.writeInt(portLocal); //
-------------------------------------------------------------- //
Trimiterea (si eventual modificarea) numelui utilizatorului // --------------------------------------------------------------
boolean existaDeja; String
mesajDialog = "Alegeti numele de utilizator!"; do { //
Alegerea numelui de utilizator
numeUser = JOptionPane.showInputDialog(mesajDialog); //
Scrierea numelui utilizatorului pe fluxul de iesire spre retea
this.outRetea.writeUTF(numeUser); //
Fortarea trimiterii (fortarea golirii bufferului)
this.outRetea.flush ();
//
Citirea rezultatului din fluxul de intrare dinspre retea
String rezultat = this.inRetea.readUTF();
existaDeja = rezultat.equals("Numele a fost deja alocat");
mesajDialog = "Numele ales exista deja. Alegeti alt nume!"; } while (existaDeja);
System.out.println("\n Clientul are numele " + numeUser); } //
-------------------------------------------------------------- //
Tratarea erorilor de conexiune //
-------------------------------------------------------------- catch (IOException ex) { //
Afisarea exceptiei
ex.printStackTrace(); } //
-------------------------------------------------------------- //
Initializari grafice //
--------------------------------------------------------------
this.setTitle("Client
" + numeUser + " : " + title);
Container containerCurent = this.getContentPane();
containerCurent.setLayout(new BorderLayout()); // Zona
de text non-editabila de iesire (cu posibilitati de defilare)
outTextGrafic = new JTextArea(8, 40);
JScrollPane panouDefilabil = new JScrollPane(outTextGrafic,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
baraDefilareVerticala = panouDefilabil.getVerticalScrollBar();
containerCurent.add("Center", panouDefilabil);
outTextGrafic.setEditable (false); // Camp
de text editabil de intrare
inTextGrafic = new JTextField(40);
containerCurent.add("South", inTextGrafic);
System.out.println("\n Configurata interfata grafica
\n"); //
-------------------------------------------------------------- //
Tratarea evenimentelor interfetei grafice (intrarea de text) //
-------------------------------------------------------------- //
Variabila locala finala (folosita in clasa interna anonima de tip //
ActionListener) final
DataOutputStream outR = this.outRetea; //
Crearea unui "ascultator" de "evenimente actionare"
ActionListener ascultatorInText = new ActionListener() { //
Tratarea actionarii intrarii de text (apasarea tastei "Enter") public
void actionPerformed(ActionEvent ev) { // Citire mesajului din intrarea de text
String intrare = inTextGrafic.getText(); try { //
Scrierea mesajului pe fluxul de iesire spre retea outR.writeUTF(numeUser + " [" +
adresaLocala + ":" + portLocal + "]> " +
intrare); //
Fortarea trimiterii mesajului (fortarea golirii bufferului)
outR.flush (); } //
In cazul unei erori legata de conexiune catch (IOException ex) { //
Afisarea exceptiei
ex.printStackTrace(); //
Inchiderea firului de executie care efectueaza receptia
firReceptie = null; } //
Pregatirea intrarii de text pentru noul mesaj (golirea intrarii)
inTextGrafic.setText (""); } }; //
Inregistrarea "ascultatorului" de "evenimente actionare"
la //
"obiectul sursa" intrare text
inTextGrafic.addActionListener(ascultatorInText); //
---------------------------------------------------------------- //
Tratarea evenimentelor interfetei grafice (inchiderea ferestrei) //
---------------------------------------------------------------- //
Crearea unui "adaptor pentru ascultator" de "evenimente
fereastra"
WindowAdapter ascultatorInchidere = new WindowAdapter() { //
Tratarea inchiderii ferestrei curente public
void windowClosing(WindowEvent ev) { //
Daca mai exista firul de executie de receptie if (firReceptie != null) { //
Inchiderea firului de receptie
firReceptie = null;
} //
Terminarea programului
System.exit(0); } }; //
Inregistrarea "ascultatorului" de "evenimente fereastra"
la "sursa" //
(fereastra curenta)
this.addWindowListener(ascultatorInchidere); //
-------------------------------------------------------------- // Lansarea
interfetei grafice //
-------------------------------------------------------------- //
Impachetarea (compactarea) componentelor in container
pack();
// Fereastra
devine vizibila - echivalent cu frame.setVisible(true)
show(); //
Cerere focus pe intrarea de text din fereastra curenta
inTextGrafic.requestFocus(); //
-------------------------------------------------------------- //
Lansarea firului de executie de receptie //
-------------------------------------------------------------- // Fir
de executie pentru receptia mesajelor de la server
firReceptie = new Thread (this); //
Lansarea firului de executie - se executa run()
firReceptie.start (); } /** * Metoda
principala a firului care receptioneaza mesaje de la server */ public void run() { //
-------------------------------------------------------------- //
Tratarea mesajelor serverului (citirea si interpretarea lor) //
-------------------------------------------------------------- try { while (true) { //
Citirea mesajului din fluxul de intrare dinspre server
String line = inRetea.readUTF (); //
-------------------------------------------------------------- //
Inregistrarea unui client nou sau preexistent // -------------------------------------------------------------- if (line.equals("Client
nou")) { //
Citirea mesajului din fluxul de intrare dinspre server
String numeClient = inRetea.readUTF (); //
Citirea mesajului din fluxul de intrare dinspre server
String adresaClient = inRetea.readUTF (); //
Citirea mesajului din fluxul de intrare dinspre server
int portClient = Integer.parseInt(inRetea.readUTF()); //
Incapsularea informatiilor privind clientul
InfoClient clientNou = new
InfoClient(numeClient, adresaClient, portClient); //
Inregistrarea clientului curent in lista (Vector)
altiClienti.addElement (clientNou);
System.out.println("Client nou: " + numeClient + " [" +
adresaClient + " : "
+ portClient + "]");
System.out.println("Lista clientilor:\n" + altiClienti.toString()); //
Anuntarea in iesirea de text a noului client
outTextGrafic.append ("Participa la conversatie si: " +
numeClient + " [" +
adresaClient + " : " +
portClient + "] \n"); } //
--------------------------------------------------------------- //
Eliminarea inregistrarii unui client care a parasit conversatia //
--------------------------------------------------------------- else
if (line.equals("Client
eliminat")) { //
Citirea mesajului din fluxul de intrare dinspre server
String numeClient = inRetea.readUTF (); //
Citirea mesajului din fluxul de intrare dinspre server
String adresaClient = inRetea.readUTF (); //
Citirea mesajului din fluxul de intrare dinspre server
int portClient = Integer.parseInt(inRetea.readUTF()); //
Incapsularea informatiilor privind clientul
InfoClient clientEliminat = new
InfoClient(numeClient, adresaClient, portClient);
altiClienti.removeElement (clientEliminat);
System.out.println("Client eliminat: " + numeClient +
" [" +
adresaClient + " : "
+ portClient + "]");
System.out.println("Lista clientilor:\n" +
altiClienti.toString()); //
Anuntarea in iesirea de text a eliminarii clientului outTextGrafic.append
("A parasit conversatia: " + numeClient + " [" +
adresaClient + " : "
+ portClient + "] \n"); } //
-------------------------------------------------------------- //
Afisarea mesajului (propriu-zis) receptionat //
-------------------------------------------------------------- else
{ //
Adaugare textului primit in iesirea de text
outTextGrafic.append (line + "\n"); } //
Solutie pentru a avea afisate intotdeauna ultimele //
mesaje primite (exista o solutie alternativa???) int
zonaVizibila = baraDefilareVerticala.getVisibleAmount(); int
valoareaMaxima = baraDefilareVerticala.getMaximum();
baraDefilareVerticala.setValue(valoareaMaxima - zonaVizibila);
validate();
repaint(); } } //
-------------------------------------------------------------- //
Tratarea erorilor de conexiune //
-------------------------------------------------------------- catch (IOException ex) { //
Afisarea exceptiei
ex.printStackTrace ();
} //
-------------------------------------------------------------- //
Curatenie finala //
-------------------------------------------------------------- finally { //
Inchiderea firului de receptie curent
firReceptie = null; //
Ascunderea intrarii de text
inTextGrafic.setVisible(false); //
Reasezarea interfetei grafice
validate (); try { //
Inchiderea fluxului de iesire spre retea
outRetea.close (); } // In
cazul unei erori legata de conexiune catch (IOException ex) { //
Afisarea exceptiei
ex.printStackTrace (); } } } /** * Metoda principala
- creaza socketul, fluxurile si lanseaza clientul * @param args[] * @param args * @throws java.io.IOException */ public static void main(java.lang.String[]
args) throws IOException { //
Adresa serverului String
adresaServer =
JOptionPane.showInputDialog("Introduceti adresa
serverului"); //
Portul serverului String
numarPort = JOptionPane.showInputDialog( "Introduceti
numarul de port al serverului"); int
portServer = Integer.parseInt(numarPort); //
Crearea socketului catre server socket =
new Socket (adresaServer, portServer);
System.out.println ("\n Client TCP lansat catre serverul [" +
socket.getInetAddress() + ":" + socket.getPort() +
"]"); //
Crearea fluxurilor, crearea si lansarea clientului grafic new
ClientDeChat_v2 (socket.getLocalPort() +
" (Server " + adresaServer + " : " +
numarPort + ")", socket.getInputStream (),
socket.getOutputStream ()); } } class
InfoClient { String nume; String adresa; int port; Thread fir; /** * @param
nume * @param
adresa * @param
port * @param
fir */ public InfoClient(String nume, String
adresa, int port, Thread fir) {
this.nume = nume;
this.adresa = adresa;
this.port = port; this.fir
= fir; } /** * @param
nume * @param
adresa * @param
port * @param
fir */ public InfoClient(String nume, String adresa,
int port) {
this.nume = nume;
this.adresa = adresa;
this.port = port; this.fir
= null; } public
void setFir(Thread fir) { this.fir
= fir; } /** * @return
java.lang.String */ public String toString() { return "\t" + nume +
"/" + adresa + ":" + port + "\n"; } /** * @return
boolean */ public boolean equals(Object obj) { if ((obj != null) && (obj
instanceof InfoClient)) {
InfoClient celalaltClient = (InfoClient)obj; return
((this.nume.equals(celalaltClient.nume)) &&
(this.adresa.equals(celalaltClient.adresa)) &&
(this.port == celalaltClient.port)); } return
false; } } |
Codul sursa Java pentru serverul de chat (si fisierul pentru compilarea si lansarea serverului)
Codul sursa Java pentru firul de tratare a clientului de chat.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//Source
file: TratareClientDeChat_v2.java /** * Server
chat simplu - componenta de tratare a unei conexiuni */ import java.net.*; import java.io.*; import java.util.*; import java.util.Vector; public class
TratareClientDeChat_v2 extends Thread { /** * Vector
de referinte la obiecte care trateaza clienti (ptr. inregistrare) */ private
static Vector listaClienti = new Vector (); /** * Socket
flux (TCP) */ private
Socket socket; /** * Flux de
intrare dinspre retea */ private
DataInputStream inRetea; /** * Flux de
iesire catre retea */ private
DataOutputStream outRetea; private
InfoClient client; /** *
Initializeaza obiectul (firul) care trateaza un nou client * @param socket * @throws java.io.IOException */ public TratareClientDeChat_v2(Socket
socket) throws IOException {
this.socket = socket; inRetea
= new DataInputStream (new
BufferedInputStream
(socket.getInputStream ())); outRetea
= new DataOutputStream (new BufferedOutputStream
(socket.getOutputStream ())); } /** * Metoda
principala a firului de executie. * Primeste mesajele si apeleaza difuzarea
lor. */ public void run() { try { //
---------------------------------------------------------------- //
Obtinerea informatiilor de la client //
---------------------------------------------------------------- //
Citirea adresei clientului din fluxul de intrare de la client String
adresaClient = inRetea.readUTF(); //
Citirea portului clientului din fluxul de intrare de la client int
portClient = inRetea.readInt(); //
---------------------------------------------------------------------- //
Obtinerea si verificarea (eventual modificarea) numelui utilizatorului //
---------------------------------------------------------------------- //
Numele clientului String
numeClient; //
Rezultatul verificarii existentei numelui in lista
boolean existaDeja; //
Receptia numelui si eventuala cerere de modificare do { //
Citirea numelui clientului din fluxul de intrare de la client
numeClient = inRetea.readUTF();
existaDeja = false; //
Enumerare creata pornind de la lista clientilor
Enumeration enum = listaClienti.elements (); //
Cat timp mai sunt elemente in enumerare while (enum.hasMoreElements ())
{ //
Protectie la acces concurent la Vectorul clientilor
synchronized (listaClienti) {
// Obtinerea informatiilor privind clientul curent tratat
InfoClient infoClient = (InfoClient) enum.nextElement(); if (numeClient.equals(infoClient.nume))
{
existaDeja = true;
break;
} }
} if (existaDeja) { //
Scrierea mesajului in fluxul de iesire al firului curent
outRetea.writeUTF("Numele a fost deja alocat"); } else
{ //
Scrierea mesajului in fluxul de iesire al firului curent
outRetea.writeUTF("Client inregistrat"); } //
Fortarea trimiterii
outRetea.flush(); } while (existaDeja); //
------------------------------------------------------------------- //
Trimiterea listei clientilor deja existenti (catre clientul tratat) //
------------------------------------------------------------------- //
Enumerare creata pornind de la lista clientilor Enumeration enum = listaClienti.elements
(); // Cat
timp mai sunt elemente in enumerare while (enum.hasMoreElements ())
{ //
Protectie la acces concurent la Vectorul clientilor
synchronized (listaClienti) { //
Obtinerea informatiilor privind clientul curent tratat
InfoClient infoClient = (InfoClient) enum.nextElement(); //
Scrierea mesajului in fluxul de iesire al firului curent
outRetea.writeUTF("Client nou");
outRetea.writeUTF(infoClient.nume);
outRetea.writeUTF(infoClient.adresa);
outRetea.writeUTF(new Integer(infoClient.port).toString());
} } //
Fortarea trimiterii
outRetea.flush(); //
------------------------------------------------------------------- //
Anuntarea existentei clientului curent (catre ceilalti clienti) //
-------------------------------------------------------------------
System.out.println("Difuzare informatii client nou ");
difuzare("Client nou");
difuzare(numeClient);
difuzare(adresaClient);
difuzare(new Integer(portClient).toString()); //
------------------------------------------------------------------- //
Inregistrarea informatiilor clientului tratat //
------------------------------------------------------------------- //
Inregistrarea informatiilor clientului curent client
= new InfoClient(numeClient, adresaClient, portClient, this); //
Inregistrarea clientului curent in lista (de tip Vector)
listaClienti.addElement (client); //
------------------------------------------------------------------- //
Afisarea in consola a informatiilor clientului curent tratat //
-------------------------------------------------------------------
System.out.println("\nNoul client [" + numeClient + "] are adresa
[" + adresaClient + "] si portul
[" + portClient +"]");
System.out.println("Lista clientilor actualizata:\n" +
listaClienti.toString()+"\n"); //
-------------------------------------------------------------- //
Tratarea mesajelor clientului (citirea si difuzarea mesajelor) //
-------------------------------------------------------------- //
Bucla infinita (repetare pana la inchiderea firului curent) while (true) { //
Citirea mesajului din fluxul de intrare de la client
String mesaj = inRetea.readUTF ();
System.out.println("Difuzare mesaj: " + mesaj); //
Difuzarea catre toti clientii curent inregistrati
difuzare (mesaj);
System.out.println(); } } //
-------------------------------------------------------------- //
Tratarea erorilor de conexiune //
-------------------------------------------------------------- catch (IOException ex) { //
Afisare exceptie
ex.printStackTrace ();
} //
-------------------------------------------------------------- // Curatenie
finala //
-------------------------------------------------------------- finally { //
Eliminarea clientului curent din lista (de tip Vector)
listaClienti.removeElement (client);
System.out.println("\nClient eliminat...");
System.out.println("Lista clientilor actualizata:\n" +
listaClienti.toString()+"\n"); //
------------------------------------------------------------------- // Anuntarea
eliminarii clientului curent (catre ceilalti clienti) //
-------------------------------------------------------------------
System.out.println("Difuzare informatii client eliminat ");
difuzare("Client eliminat"); difuzare(client.nume);
difuzare(client.adresa);
difuzare(new Integer(client.port).toString()); try { //
Inchiderea socketului
socket.close (); } // In
cazul unei erori legata de conexiune catch
(IOException ex) { //
Afisarea exceptiei
ex.printStackTrace ();
} } } /** *
Difuzeaza mesajul primit catre clienti * @param mesaj */ private static void difuzare(String mesaj)
{ // Enumerare creata pornind de la lista
clientilor
Enumeration enum = listaClienti.elements (); // Cat
timp mai sunt elemente in enumerare while (enum.hasMoreElements ())
{ //
Referinta catre firul curent initializata cu null
TratareClientDeChat_v2 firDestinatie = null; //
Protectie la acces concurent la Vectorul clientilor
synchronized (listaClienti) { //
Obtinerea informatiilor privind clientul curent
InfoClient infoClient = (InfoClient) enum.nextElement();
System.out.print(" - catre: " + infoClient.toString()); //
Obtinerea referintei catre firul curent
firDestinatie = (TratareClientDeChat_v2) infoClient.fir; //
Daca referinta e valida if (firDestinatie != null) { try {
// Protectie la acces concurent la fluxul de iesire
synchronized (firDestinatie.outRetea) {
// Scrierea mesajului in fluxul de iesire al firului curent
firDestinatie.outRetea.writeUTF (mesaj);
}
// Fortarea trimiterii mesajului
firDestinatie.outRetea.flush (); } //
In cazul unei erori legata de conexiune catch (IOException ex) {
// Inchiderea firului curent
listaClienti.remove(infoClient);
firDestinatie = null;
}
} } } } } class
InfoClient { String nume; String adresa; int port; Thread fir; /** * @param
nume * @param
adresa * @param
port * @param
fir */ public InfoClient(String nume, String
adresa, int port, Thread fir) {
this.nume = nume;
this.adresa = adresa;
this.port = port; this.fir
= fir; } /** * @return
java.lang.String */ public String toString() { return
fir.toString() + "(" + nume + "/" + adresa +
":" + port + ")\n";
} /** * @return
boolean */ public boolean equals(Object obj) { if ((obj != null) && (obj
instanceof InfoClient)) {
InfoClient celalaltClient = (InfoClient)obj; return
((this.nume.equals(celalaltClient.nume)) &&
(this.adresa.equals(celalaltClient.adresa)) &&
(this.port == celalaltClient.port)); } return
false; } } |