Nutzen Sie die Klassen des Pakets Vorlage. Die Ausgangslage enthält je ein vollständiges Client- und Server-GUI, welche zusammen mit den Klassen Client und Server (beide noch zu vervollständigen) lauffähig sind.
- Ergänzen Sie die Klasse Server mit dem Code für die Netzwerkverbindung. Ein ServerSocket wird initialisiert und wartet auf eine Client-Verbindung. Wird eine Verbindung etabliert, soll der Server String um String vom InputStream der Netzwerkverbindung lesen und in der ServerView ausgeben.
- Erweitern Sie nun den Client, dass er eine Verbindung mit dem Server aufbaut und die Strings der Eingabe nicht auf der Konsole ausgibt, sondern in den OutputStream der Netzwerkverbindung schreibt.
Sie sollten nun in der Lage sein, mit Ihrem Nachbarn zu kommunizieren. Versuchen Sie es!
Die Vorlage schleift die Kommandozeilenparameter an die Client respektive die Serverklasse durch. Hier sollten Sie auf Seiten des Client Portnummer und ggf. Servername und auf Seiten des Servers die Portnummer erwarten.
Zu starten sind jeweils ServerView und ClientView.
Die Lösung der ersten Aufgabe hat den Nachteil, dass nur ein einziger Client auf das Writeboard schreiben kann. Sie kennen ja schon Serverarchitekturen für viele Clients.
- Schreiben Sie die Klasse ClientConnection, welche den Client auf der Serverseite repräsentiert und von Thread abgeleitet ist. Bauen Sie den Server entsprechend um, dass er in der run()-Methode Verbindungen mit Clients aufbaut und pro Client ein ClientConnection-Objekt instanziert und startet. Nun werden die Strings in der run()-Methode des ClientConnection-Objekts eingelesen.
- Der Server zeigt nun alle Messages der Clients an. Damit die Messages von den unterschiedlichen Clients auseinander gehalten werden können, soll der Client als Bestandteil jedes Strings den eigenen Namen mitschicken:
Monika: halli, hallo!
Patrick: ebenfalls
...
Sie sollten nun in der Lage sein, mit mehreren Nachbarn zu kommunizieren. Einer soll seinen Server starten, und die andern versuchen, auf dessen Writeboard zu schreiben.
Alternativ können Sie auch den Server mit einer anderen Architektur (z.B: Leader-Followers) oder mittels inner class Runnable() implementieren.
Beim Client sollen Serverport, Servername und Benutzername angegeben werden.
Befindet sich der Server auf einem andern Rechner, so sieht man die Messages nicht. Server und Client sollen nun so umgebaut werden, dass alle Messages an alle Clients verteilt und angezeigt werden.
- Der Client muss nun ebenfalls in einem Thread laufen und auf einkommende Nachrichten warten. Das GUI wird erweitert, dass die Messages dargestellt werden können. Dazu kann die ServerView praktisch 1:1 übernommen und in die ClientView integriert werden.
- Der Server verwaltet die Client-Verbindungen und verteilt ankommende Messages an alle Clients.
Nun haben wir ein funktionierendes Chat-Programm auf Client/Server-Basis.
Noch ist die Handhabung nicht besonders komfortabel. Unser Chat-Programm soll deshalb erweitert werden.
- Client und Server sollen über das entsprechende GUI parametrisiert und gestartet resp. gestoppt werden können.
- Wir wissen nicht, wer alles am Chat-Server angemeldet ist, und wir können nicht individuelle Nachrichten an einzelne Chat-Teilnehmer schicken. Mit der Einführung eines Protokolls soll dies geändert werden. Ein Client meldet sich beim Server an und ab, was an alle Clients weitergeleitet wird. Ebenso können Nachrichten an alle oder individuelle Chat-Teilnehmer weitergeleitet werden. Erweitern Sie Client, Server und die GUIs mit diesen Optionen.
Falls Ihnen die java.net Sockets zu "langweilig" sind, können Sie versuchen Client oder Server mittels java.nio zu lösen. Nutzen Sie den Reactor aus der Vorlesung um den Chat ohne multi-threading zu implementieren.
JavaReactor