Sunteți pe pagina 1din 7

Aplicatii client-server bazate pe socket TCP si interfete grafice Swing

Studenti: Pavel Victor-Cristian Minca Anca Grupa: 421 E

1.Descrierea claselor si metodelor utilizate


Proiectul de fata contine 4 clase: - ClientChatN2N - ServerChatN2N - DialogUtilizator - ConexiuneRetea Din numele acestor clase reiese foarte clar rolul lor.Primele doua clase sunt clasele principale,ele se vor rula,clasa ServerChatN2N pentru server si clasa ClientChatN2N pentru clienti,in timp ce clasele DialogUtilizator si ConexiuneRetea sunt clase de "suport", DialogUtilizator fiind folosit pentru a afisa interfata cu utilizatorul (atat pentru client cat si pentru server), iar clasa ConexiuneRetea fiind folosita de catre client si server pentru a intermedia conexiunile realizate de aceste doua programe. Prezentarea Claselor:

ConexiuneRetea
Dupa cum am mai spus, rolul acestei clase este de a intermedia conexiunile. Ea are urmatorii 3 membri privati: - conexiune (Socket) - scannerTCP (Scanner) - printerTCP (PrintStream) Socket-ul (conexiune) reprezinta efectiv conexiunea care are loc intre client si server. Practic Socket-ul este ca un fir prin care se transmite informatia, de la o sursa catre o adresa. In exemplul current folosim adrese de IP cu TCP (Transmition Control Protocol). Pentru a putea opera pe acest socket, avem nevoie de doua operatii de baza: scrierea de informatii pe socket si citirea de informatii de pe socket. Pentru aceasta, vom folosi Scanner (citire) si PrintStream (scriere). Constructorul acestei clase initializeaza o conexiune pe baza unui socket primit ca parametru in constructor. Cele doua metode (getLocalAddress si getRemoteAddress) ne furnizeaza informatii despre adresa locala si adresa destinatie a conexiunii. Adresa locala este cea a calculatorului care a initiat conexiunea. Adresa remote este cea a serverului. Metodele nextLine si printLine(String) se folosesc pentru a citi urmatoarele informatii pregatite de conexiunea respectiva pentru a trimite mesaje pe conexiune. Practic nextLine este echivalentul lui read, iar printLine este echivalentul pentru write. Scrierea si citirea de pe socketuri abstractizeaza cu success modelul de baza 2

al scrierii si citirii in java. In concluzie, rolul acestei clase este de a trimite si primi mesaje de pe o conexiune.

DialogUtilizator
Rolul acestei clase este de a intermedia comunicatia cu utlizatorul, prezentandu-I interfata grafica. Interfata grafica este compusa din: - o caseta de text unde apar mesajele (atat cele de la client cat si la server) - o caseta de text unde se introduc mesajele care se trimit - butonul de BYE (bonus) Intrucat responsabilitatea comunicatiei nu apartine acestei clase, ci a clasei ConexiuneRetea, clasa DialogUtilizator are o metoda setConexiune(Socket) In interiorul constructorului se creeaza toate elemente grafice ale ferestrei. Aceasta clasa extinde JFrame pentru a putea afisa o fereastra. Se declara control cu control, iar apoi se adauga la container. Layout-ul containerului este de tip BorderLayout. Metodele nextLine si printLine nu au ca rol comunicatia cu socket-ul (cum era la clasa ConexiuneRetea). In schimb, aceste metode sunt chemate din clasele ServerChatN2N si ClientChatN2N. Asadar, in aceasta clasa aceste doua metode au ca rol interactiunea cu casetele de text (scriere si citire din casetele de text). Clasa locala AscultatorText implementeaza ActionListener. Metoda actionPerformed este chemata atunci cand se apasa tasta enter. In acel moment, textul scris in caseta de text este trimis catre Client sau Server, care mai departe, cu ajutorul lui ConexiuneRetea se trimite pe retea prin Socket.

ServerChatN2N
Clasa ServerChatN2N reprezinta serverul. Acesta se foloseste de un DialogUtilizator, de un vector de conexiuni si de un socket de server (pentru a putea sta in starea de Listen). In momentul rularii (metoda main), acesta cere numarul de port de care va asculta. Este necesar ca sa nu mai fie deja folosit, intrucat o eroare va fi afisata (exceptii bonus). Dupa crearea socketului in stare de ascultare, se incepe o bucla infinita unde se primesc conexiuni, si pentru fiecare client care doreste sa se conecteze se adauga la vectorul de conexiuni, se construieste serverul si se ruleaza Thread-ul pe care acesta se bazeaza.. In interiorul acestui thread, daca exista mesaje care asteapta sa fie primite, se 3

primesc si se trimit la toti clientii conectati, folosind un for peste vectorul de conexiuni. Am adaugat interfata grafica si clasei ServerChatN2N astfel incat mesajele primite de server vor putea fi vazut cu textul "ClientNR" la inceput,pentru a putea sti de la ce client provin(bonus). Daca in schimb se primeste text-ul BYE, thread-ul se opreste si conexiunea se elibereaza.

ClientChatN2N
Aceasta clasa reprezinta fiecare client care se conecteaza. Se foloseste de un DialogUtilizator pentru interactiunea cu utilizatorul, de o ConexiuneRetea pentru interactiunea cu reteaua si trimiterea/primirea mesajelor. Ca si clasa ServerChatN2N, ClientChatN2N extinde clasa Thread. In constructorul acestei clase, clientului, i se citesc de la utilizator numarul de port al serverului si adresa de IP a serverului. Daca se poate efectua conexiunea, thread-ul incepe sa ruleze, ceea ce il face sa primeasca fiecare mesaj pe care ceilalti clienti il trimit serverului, si server-ul il trimite catre client. Similar cu Server-ul, daca se primeste BYE, atunci clientul se inchide.

2.Probleme intampinate si solutii tehnice


In urma implementarii codului sursa scris in laboratoarele 5 si 6 am intampinat urmatoarele probleme:

Ciclu infinit care bloca serverul


Atunci cand porneam clientul, aparea pe ecran in continuu Introduceti mesajul. Pentru a remedia aceasta problema am sters while-ul din main-ul ClientChatN2N. Practic acum procesarea se face prin thread.

Conexiune nedefinita pentru client


Atunci cand trimiteam un mesaj prin client (desi acesta era conectat) se arunca o exceptie. Urmarind fluxul de executie, am ajuns in metoda actionPerformed din AscultatorInText. Acolo, codul arunca exceptie la conexiune.printLine, si am descoperit ca variabila conexiune era NULL, aruncandu-se o NullPointerException. 4

Apoi am observat ca legatura de conexiune dintre ClientChatN2N, DialogUtilitizator si ConexiuneRetea nu era facuta bine. Astfel, am adaugat in ClientChatN2N, in constructor linia de cod: dialog.setConexiune(conexiune); si am remediat problema.

3.Mod de utilizare al proiectului


Proiectul are doua clase pe care le vom rula:ServerCharN2N si ClientChatN2N.

Serverul (ServerChatN2N)
Atunci cand se ruleaza server-ul apare mai intai o caseta de dialog care ne cere portul pe care va rula serverul.

Dup aceea se apasa OK, apare fereastra principala a serverului:

In acest moment serverul este pregatit sa accepte conexiuni din partea clientilor care se conecteaza la IP-ul si portul pe care este el deschis.

Clientul (ClientChatN2N)
Atunci cand se ruleaza client-ul apare mai intai o caseta de dialog care ne cere portul pe care se va conecta clientul:

Apoi va aparea o caseta care va cere IP-ul serverului la care ne vom conecta:

Dupa ce se scrie un mesaj si se da enter, acesta apare in caseta mare de text. Acum vom mai rula inca un client, pentru a vedea cum mesajele se propaga intre clienti, cu ajutorul serverului.

Mesajul scris de clientul 2 (cel de sus) a aparut si in clientul 1(cel de jos). Practic orice mesaj scris de orice client se poate vedea imediat in oricare alt client conectat la server in acel moment si se va putea vedea si de la server avand si un nume corespunzator.

S-ar putea să vă placă și