Diferență între revizuiri ale paginii „POO Lab Lucrarea 5”
De la WikiLabs
Jump to navigationJump to searchLinia 21: | Linia 21: | ||
# Adăugați clasei <code style="color: green">seriaf.poo.structs.Message</code> o metodă getter publică pentru expeditor, numită <code style="color: green">String getSender()</code>. | # Adăugați clasei <code style="color: green">seriaf.poo.structs.Message</code> o metodă getter publică pentru expeditor, numită <code style="color: green">String getSender()</code>. | ||
# Pentru a putea trimite corect mesajele private, clasa <code style="color: green">seriaf.poo.server.ServerPeer</code> trebuie să aibă o metodă publică numită <code style="color: green">String getUsername()</code> care să întoarcă numele client-ului conectat la acel ServerPeer. Numele este stocat în clasă într-un câmp privat, care se actualizează la fiecare mesaj primit, extrăgând din mesaj numele expeditorului. | # Pentru a putea trimite corect mesajele private, clasa <code style="color: green">seriaf.poo.server.ServerPeer</code> trebuie să aibă o metodă publică numită <code style="color: green">String getUsername()</code> care să întoarcă numele client-ului conectat la acel ServerPeer. Numele este stocat în clasă într-un câmp privat, care se actualizează la fiecare mesaj primit, extrăgând din mesaj numele expeditorului. | ||
− | # Modificați clasa <code style="color: green">seriaf.poo.server.Server</code> scrisă la tema anterioară, astfel încât la conectarea unui client, aceasta să creeze un nou <code style="color: green">seriaf.poo. | + | # Modificați clasa <code style="color: green">seriaf.poo.server.Server</code> scrisă la tema anterioară, astfel încât la conectarea unui client, aceasta să creeze un nou <code style="color: green">seriaf.poo.server.ServerPeer</code> pe care să-l pornească ca Thread, apoi să revină în metoda <code style="color: green">ServerSocket.accept()</code>, așteptând o nouă conexiune. |
+ | # Clasa <code style="color: green">seriaf.poo.server.Server</code> trebuie acum să fie instanțiabilă. Adăugați un constructor care să ia ca argument port-ul TCP pe care server-ul sa asculte și numărul maxim de clienți posibili. | ||
+ | # Bucla cu apelul metodei '''accept''' <code style="color: green">seriaf.poo.server.Server</code> trebuie acum să fie mutată într-o metodă separată a clasei <code style="color: green">seriaf.poo.server.Server</code> numită '''listen'''. | ||
+ | # În metoda '''main''' din <code style="color: green">seriaf.poo.server.Server</code> trebuie să rămână o instanțiere de obiect <code style="color: green">seriaf.poo.server.config.ServerConfig</code>, o instanțiere de obiect <code style="color: green">seriaf.poo.server.Server</code> și un apel de metodă '''listen()''', cu blocurile '''try-catch''' necesare. | ||
+ | # Clasa <code style="color: green">seriaf.poo.server.Server</code> trebuie să mai conțină două metode, <code style="color: green">void dispatch(Message)</code> și <code style="color: green">void removeClient(ClientPeer)</code>. Prima este apelată de către obiectele de tip <code style="color: green">seriaf.poo.server.ServerPeer</code> cu mesajele primite de la clienți, și are rolul de a le trimite mai departe, către ceilalți clienți. A doua metodă este apelată când un client de deconectează (void sau datorită unei erori), pentru a fi elimiat din listă. | ||
# Server-ul nu trebuie să accepte o conexiune dacă numărul de clienți conectați este deja egal cu proprietatea MAX_CLIENTS citită din fișierul ''server.conf'' de către <code style="color: green">seriaf.poo.server.config.ServerConfig</code>. | # Server-ul nu trebuie să accepte o conexiune dacă numărul de clienți conectați este deja egal cu proprietatea MAX_CLIENTS citită din fișierul ''server.conf'' de către <code style="color: green">seriaf.poo.server.config.ServerConfig</code>. | ||
Versiunea de la data 26 noiembrie 2015 13:17
Noțiuni și cunoștințe necesare
- Paradigma Obiect-Orientare; Clase și obiecte
- Noțiuni despre Java
- Realizarea și execuția unui program Java
- Sintaxa limbajului Java; Structura lexicală a unui program
- Convenții de programare
- Noțiuni avansate de programare obiect-orientată
- Java Application Programming Interface (API)
- Stream-uri de Input/Output
- Tratarea excepțiilor
- Serializarea obiectelor
- Socket-uri de rețea
- Programare concurentă - fire de execuție (Threads)
Cerințe
- Modificați clasa
seriaf.poo.client.ClientPeer
scrisă la tema anterioară, transformând-o într-un fir de execuție care în paralel cu firul principal de execuție, să citească obiecte de tipseriaf.poo.structs.Message
dinspre server și să le afișeze pe ecran. Acest thread, odată instanțiat, trebuie pornit de către clasaseriaf.poo.client.TextClient
. - Modificați clasa
seriaf.poo.server.ServerPeer
scrisă la tema anterioară, transformând-o într-un fir de execuție. Acest fir nou de execuție trebuie să citească obiectele de tipseriaf.poo.structs.Message
șiseriaf.poo.structs.PrivateMessage
de la clientul asociat și să le distribuie corect la ceilalți clienți. - Pentru a putea retransmite mesajele celorlalți clienți, clasa
seriaf.poo.server.ServerPeer
trebuie să aibă o metodă publicăvoid sendMessage(Message)
care să serializeze obiectul primit ca argument către clientul conectat. - Adăugați clasei
seriaf.poo.structs.Message
o metodă getter publică pentru expeditor, numităString getSender()
. - Pentru a putea trimite corect mesajele private, clasa
seriaf.poo.server.ServerPeer
trebuie să aibă o metodă publică numităString getUsername()
care să întoarcă numele client-ului conectat la acel ServerPeer. Numele este stocat în clasă într-un câmp privat, care se actualizează la fiecare mesaj primit, extrăgând din mesaj numele expeditorului. - Modificați clasa
seriaf.poo.server.Server
scrisă la tema anterioară, astfel încât la conectarea unui client, aceasta să creeze un nouseriaf.poo.server.ServerPeer
pe care să-l pornească ca Thread, apoi să revină în metodaServerSocket.accept()
, așteptând o nouă conexiune. - Clasa
seriaf.poo.server.Server
trebuie acum să fie instanțiabilă. Adăugați un constructor care să ia ca argument port-ul TCP pe care server-ul sa asculte și numărul maxim de clienți posibili. - Bucla cu apelul metodei accept
seriaf.poo.server.Server
trebuie acum să fie mutată într-o metodă separată a claseiseriaf.poo.server.Server
numită listen. - În metoda main din
seriaf.poo.server.Server
trebuie să rămână o instanțiere de obiectseriaf.poo.server.config.ServerConfig
, o instanțiere de obiectseriaf.poo.server.Server
și un apel de metodă listen(), cu blocurile try-catch necesare. - Clasa
seriaf.poo.server.Server
trebuie să mai conțină două metode,void dispatch(Message)
șivoid removeClient(ClientPeer)
. Prima este apelată de către obiectele de tipseriaf.poo.server.ServerPeer
cu mesajele primite de la clienți, și are rolul de a le trimite mai departe, către ceilalți clienți. A doua metodă este apelată când un client de deconectează (void sau datorită unei erori), pentru a fi elimiat din listă. - Server-ul nu trebuie să accepte o conexiune dacă numărul de clienți conectați este deja egal cu proprietatea MAX_CLIENTS citită din fișierul server.conf de către
seriaf.poo.server.config.ServerConfig
.
Note:
- Clasa Server ar trebui să păstreze o listă cu toți clienții conectați (cu obiectele de tip ServerPeer). Pentru acest lucru vă puteți folosi de clasa java.util.ArrayList.
- Această listă trebuie să fie menținută în sensul că noii clienți trebuie adăugați, iar clienții deconectați trebuie eliminați.
- Această listă ar trebui să fie accesibilă firelor de execuție de tip ServerPeer prin metode sincronizate.
- Pentru a verifica dacă un obiect e instanță a unei clase anume, puteți folosi operatorul instanceof:
Object o = ois.readOject();
if(o instanceof String){
String s = (String)o;
System.out.print(s);
}else{
System.out.print("The object is not a String!");
}