IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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

 

Všetky články v sekcii
Java - Pre pokročilých
Článok pre vás napísal Filip Stryk
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity