import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; public class ChatClient extends java.applet.Applet implements ActionListener, Observer { TextArea other; TextField own; TextField name; Button send; SocketHandler handler; /** * Layout des Client erstellen und einen Kommunikationskanal * zum Server öffnen */ public void init() { other = new TextArea(); own = new TextField(); name = new TextField("Unbenannt"); send = new Button("Senden"); send.addActionListener(this); Panel south = new Panel(new BorderLayout()); south.add("West", name); south.add("Center", own); south.add("East", send); setLayout(new BorderLayout()); add("Center", other); add("South", south); System.err.println(this.getDocumentBase().getHost()); try { String host = this.getDocumentBase().getHost(); // Wenn das Applet nicht über einen Webserver geladen // wurde, dann ist kein Host definiert. if (host == null || host.equals("")) host = "localhost"; handler = new SocketHandler(new Socket(host, 8090)); handler.addObserver(this); Thread thread = new Thread(handler); thread.start(); } catch (Exception e) { other.setText("Dieses Applet muss von einem Webserver geladen werden!"); } } /** * Der Benutzer schreibt einen Satz */ public void actionPerformed(ActionEvent ev) { try { handler.write(name.getText() + ": " + own.getText()); own.setText(""); } catch (Exception ex) { ex.printStackTrace(); } } /** * Ein Satz wird vom Server geliefert. */ public void update(Observable o, Object arg) { other.setText(other.getText() + arg + "\n"); } } --- Neue Klasse --- import java.net.*; import java.util.*; /** * Der Server nimmt Texte entgegen und sendet diese an alle * verbundenen Clients. */ public class ChatServer extends Thread implements Observer { Vector handlers = new Vector(); public static void main(String[] args) { ChatServer cs = new ChatServer(); cs.start(); } /** * In der run() werden neue Verbindungen zu ChatClients * aufgebaut */ public void run() { ServerSocket socket; Socket chat; System.out.println("Starte ChatServer ..."); try { socket = new ServerSocket(8090); } catch (Exception e) { return; } // Die Hauptroutine des Chat-Servers while(true) { try { // Der Aufruf von accept() blockiert solange, bis sich ein // neuer Client mit einem Request an den Server wendet chat = socket.accept(); System.out.println("Client angemeldet ..."); // Es wird ein neuer Socket-Handler erzeugt, der // Texte über die Verbindung versendet und empfängt. SocketHandler handler = new SocketHandler(chat); handler.addObserver(this); Thread thread = new Thread(handler); thread.start(); handlers.add(handler); } catch (Exception e) { e.printStackTrace(); } } } /** * Es liegt ein Text eines Clients vor. Der Text wird nun * an alle verbundenen Clients verschickt. Wenn ein Client * nicht mehr reagiert, dann wird er aus der Liste der * Clients gestrichen. */ public synchronized void update(Observable o, Object arg) { int i = handlers.size()-1; while (i >= 0) { SocketHandler tmp = (SocketHandler)handlers.elementAt(i); try { tmp.write(""+arg); } catch (Exception ignore) { handlers.removeElement(tmp); tmp.stopNow(); System.out.println("Client abgemeldet ..."); } i--; } } } --- Neue Klasse --- import java.util.Observable; import java.net.Socket; import java.io.*; /** * Die Klasse für die Kommunikation. Die Klasse sendet * und empfängt Texte. */ public class SocketHandler extends Observable implements Runnable { Socket socket; OutputStream os; boolean stop = false; public SocketHandler(Socket socket) throws IOException { this.socket = socket; this.os = socket.getOutputStream(); } /** * Der Klasse horcht am Kommunikationskanal auf ankommende * Nachrichten und informiert interessierte Objekte, wenn * ein neuer Text vorliegt. */ public void run() { try { InputStream is = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String text; while(!stop && (text = reader.readLine()) != null) { System.out.println("-> " + text); // Alle Observer benachrichtigen setChanged(); notifyObservers(text); } } catch (Exception e) {} close(); } /** * Einen Text an den Kommunikationspartner verschicken */ public void write(String text) throws IOException { System.out.println("<- " + text); os.write((text + "\n").getBytes()); } /* * Den Thread stoppen */ public void stopNow() { stop = true; } /** * Den Kommunikationskanal abbauen */ public void close() { try { os.close(); socket.close(); } catch(Exception ignore) {} } }