Documente Academic
Documente Profesional
Documente Cultură
Chișinău – 2020
Sarcina lucrarii:
Să se creeze o aplicație Client-Server TCP utilizând Sockets API
Mersul lucrarii:
Scopul acestei lucrari de laborator este de a crea o aplicatie de tip chat. Aplicatia se
poate rula pe diferite calculatoare conectate la o retea locala. Pot exista mai multi
clienti care se conecteaza la server si pot discuta intre ei. După ce s-a conectat la
server, un utilizator trebuie să-și furnizeze numele său pentru a intra în chat. Serverul
trimite o listă de utilizatori online în prezent la noul utilizator. Fiecare utilizator este
notificat la sosirea unui nou utilizator și la plecarea acestuia. Fiecare mesaj este
prefixat cu numele de utilizator pentru a urmări cine a trimis mesajul. Și în final,
utilizatorul spune „bye” să renunțe la chat. Aplicația constă din două părți: server și
client. Fiecare parte poate rula independent pe computere separate.
Partea server
while (true) {
Socket socket = serverSocket.accept();
System.out.println("New user connected");
Set<String> getUserNames() {
return this.userNames;
}
boolean hasUsers() {
return !this.userNames.isEmpty();
}
Clasa ChatServer are doua colectii Set pentru a urmari numele si firele clientilor
conectati. Set este folosit pentru evitarea dublicatelor si pentru ca ordinea elementelor
nu conteaza.
O metoda importanta din clasa ChatServer este broadcast() care transmite un mesaj de
la client tuturor celorlalti clienti.
printUsers();
String clientMessage;
do {
clientMessage = reader.readLine();
serverMessage = "[" + userName + "]: " + clientMessage;
server.broadcast(serverMessage, this);
} while (!clientMessage.equals("bye"));
server.removeUser(userName, this);
socket.close();
void printUsers() {
if (server.hasUsers()) {
writer.println("Connected users: " + server.getUserNames());
} else {
writer.println("No other users connected");
}
}
Partea client
String getUserName() {
return this.userName;
}
}
Clasa ReadThread este responsabila de citirea intrarilor de la server si imprimarea lor
in mod repetat in consola.
public class ReadThread extends Thread {
try {
InputStream input = socket.getInputStream();
reader = new BufferedReader(new InputStreamReader(input));
} catch (IOException ex) {
System.out.println("Error getting input stream: " + ex.getMessage());
ex.printStackTrace();
}
}
if (client.getUserName() != null) {
System.out.print("[" + client.getUserName() + "]: ");
}
} catch (IOException ex) {
System.out.println("Error reading from server: " + ex.getMessage());
ex.printStackTrace();
break;
}
}
}
try {
OutputStream output = socket.getOutputStream();
writer = new PrintWriter(output, true);
} catch (IOException ex) {
System.out.println("Error getting output stream: " + ex.getMessage());
ex.printStackTrace();
}
}
String text;
do {
text = console.readLine("[" + userName + "]: ");
writer.println(text);
} while (!text.equals("bye"));
try {
socket.close();
} catch (IOException ex) {
Motivele pentru a rula aceste două fire simultan este faptul că operația de citire
blochează întotdeauna firul curent (atât citirea intrării utilizatorului de pe linia de
comandă, cât și intrarea serverului de citire prin rețea). Asta înseamnă că, dacă thread-
ul curent așteaptă intrarea utilizatorului, nu poate citi intrarea de pe server.
Prin urmare, două fire separate sunt utilizate pentru a face clientul să răspundă: poate
afișa mesaje de la alți utilizatori în timp ce citește mesajul utilizatorului curent.
Rezultate:
Partea server – conectarea a doi client si apoi iesirea unuia din chat.
Partea client:
Concluzie: