import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; /** *

* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018 *

*

* Klasse Client *

*

* Objekte von Unterklassen der abstrakten Klasse Client ermoeglichen * Netzwerkverbindungen zu einem Server mittels TCP/IP-Protokoll. Nach * Verbindungsaufbau koennen Zeichenketten (Strings) zum Server gesendet und von * diesem empfangen werden, wobei der Nachrichtenempfang nebenlaeufig geschieht. * Zur Vereinfachung finden Nachrichtenversand und -empfang zeilenweise statt, * d. h., beim Senden einer Zeichenkette wird ein Zeilentrenner ergaenzt und beim * Empfang wird dieser entfernt. Jede empfangene Nachricht wird einer * Ereignisbehandlungsmethode uebergeben, die in Unterklassen implementiert werden * muss. Es findet nur eine rudimentaere Fehlerbehandlung statt, so dass z.B. * Verbindungsabbrueche nicht zu einem Programmabbruch fuehren. Eine einmal * unterbrochene oder getrennte Verbindung kann nicht reaktiviert werden. *

* * @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule * @version 30.08.2016 */ public abstract class Client { private MessageHandler messageHandler; private class MessageHandler extends Thread { private SocketWrapper socketWrapper; private boolean active; private class SocketWrapper { private Socket socket; private BufferedReader fromServer; private PrintWriter toServer; public SocketWrapper(String pServerIP, int pServerPort) { try { socket = new Socket(pServerIP, pServerPort); toServer = new PrintWriter(socket.getOutputStream(), true); fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException e) { socket = null; toServer = null; fromServer = null; } } public String receive() { if(fromServer != null) try { return fromServer.readLine(); } catch (IOException e) { } return(null); } public void send(String pMessage) { if(toServer != null) { toServer.println(pMessage); } } public void close() { if(socket != null) try { socket.close(); } catch (IOException e) { /* * Falls eine Verbindung getrennt werden soll, deren Endpunkt * nicht mehr existiert bzw. ihrerseits bereits beendet worden ist, * geschieht nichts. */ } } } private MessageHandler(String pServerIP, int pServerPort) { socketWrapper = new SocketWrapper(pServerIP, pServerPort); start(); if(socketWrapper.socket != null) active = true; } public void run() { String message = null; while (active) { message = socketWrapper.receive(); if (message != null) processMessage(message); else close(); } } private void send(String pMessage) { if(active) socketWrapper.send(pMessage); } private void close() { if(active) { active = false; socketWrapper.close(); } } } public Client(String pServerIP, int pServerPort) { messageHandler = new MessageHandler(pServerIP, pServerPort); } public boolean isConnected() { return(messageHandler.active); } public void send(String pMessage) { messageHandler.send(pMessage); } public void close() { messageHandler.close(); } public abstract void processMessage(String pMessage); }