Komunikácia Klient / Server - 3. diel - Úprava servera
Zdravím u poslednej časti tejto minisérie o socketu v Jave, v ktorej si vytvárame jednoduchú komunikáciu klient / server. Dnes si server upravíme tak, aby sa na neho mohlo pripojiť viac klientov. Urobíme to pomocou vlákien, takže vám odporúčam si najskôr prečítať článok o Multithredingu v Jave, aby ste pochopili, čo to tá vlákna sú, pretože to tu nebudem nijako zvlášť rozoberať.
Najskôr si vytvoríme novú privátne metódu s názvom clients.
private void clients() { }
Triede pridáme jeden privátny atribút ArrayList <BufferedReader> menom clientBufReaders. Z konstruktoru odstránime všetko okrem inicializácia serverSocketu a pridáme inicializáciu clientBufReaders. Nakoniec zavoláme našu novú metódu clients.
public Server() { try { this.serverSocket = new ServerSocket(8080); System.out.print("Spuštění serveru proběhlo úspěšně.\nČekám na připojení klienta...\n"); this.clientBufReaders = new ArrayList<BufferedReader>(); this.clients(); } catch (IOException e ) { e.printStackTrace(); } }
V metóde clients si vytvoríme nové vlákno menom acceptThread, ktorému ako argument odovzdáme rozhranie Runnable s metódou run (). V metóde run si vytvoríme zas nekonečný cyklus while.
Thread acceptThread = new Thread(new Runnable() { public void run() { while(true) { } } });
V cykle while si vytvoríme Socket pre klienta, menom clientSocket. Do ArrayList clientBufReaders si pridáme BufferedReader pre novo pripojeného klienta. A vypíšeme hlášku a pripojenia klienta a nezabudneme to celé zasa obaliť do bloku try - catch.
try { Socket clientSocket = serverSocket.accept(); clientBufReaders.add(new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))); System.out.println("Klient se připojil."); } catch (IOException e) { e.printStackTrace(); }
Mimo metódu run si zavoláme na acceptThread metódu štart () pre spustenie nového vlákna, ktoré sme si vytvorili.
acceptThread.start();
Vytvoríme ďalší nekonečný while cyklus a v ňom sekcii synchronized, aby sme mohli z tohto vlákna pristupovať do clientBufReaders a nedošlo k race condition. Bez synchronizácie by bol problém keby k listu obe vlákna pristúpila v rovnakú chvíľu, viac o synchronizácie vlákien v sekcii Viacvláknové aplikácie v Jave.
while(true) { synchronized(clientBufReaders) { } }
Teraz už zostáva len posledná vec a to vytvoriť si for cyklus, ktorým postupne proiterujeme ArrayList a pokiaľ bude BufferedReader nejakého klienta obsahovať text, tak si ho vypíšeme.
for(BufferedReader in : clientBufReaders) { try { if(in.ready()) { System.out.println(in.readLine()); } else { } } catch (IOException e) { e.printStackTrace(); } }
Konečne kompletný zdrojový kód by mal vyzerať takto:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class Server { private ServerSocket serverSocket; private ArrayList<BufferedReader> clientBufReaders; public static void main(String[] args) { Server server = new Server(); } public Server() { try { this.serverSocket = new ServerSocket(8080); System.out.print("Spuštění serveru proběhlo úspěšně.\nČekám na připojení klienta...\n"); this.clientBufReaders = new ArrayList<BufferedReader>(); this.clients(); } catch (IOException e ) { e.printStackTrace(); } } private void clients() { Thread acceptThread = new Thread(new Runnable() { public void run() { while(true) { try { Socket clientSocket = serverSocket.accept(); clientBufReaders.add(new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))); System.out.println("Klient se připojil."); } catch (IOException e) { e.printStackTrace(); } } } }); acceptThread.start(); while(true) { synchronized(clientBufReaders) { for(BufferedReader in : clientBufReaders) { try { if(in.ready()) { System.out.println(in.readLine()); } else { } } catch (IOException e) { e.printStackTrace(); } } } } } }
A toto je koniec minisérie o socket v Jave. Pod článkom máte samozrejme celý zdrojový kód na stiahnutie.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 165x (31.24 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java