Sie sind auf Seite 1von 30

Theodor-Heuss-Gymnasium

Jahrgangsstufe 12, 2. Hj

FACHARBEIT im Grundkurs Informatik bei

Die Funktionsweise eines Servers


Realisierung eines netzwerkbasierten Wettbewerbssystems am Beispiel von Othello

Verfasser: Jahrgangsstufe: 12 Schuljahr: Kursleiter: 2011/12

-2-

Inhaltsverzeichnis
1 Einleitung.......................................................................................................................3 2 Othello...........................................................................................................................3 2.1 Aufbau und Spielregeln...........................................................................................3 2.2 Beispiele fr Spielsituationen..................................................................................4 3 Der Server......................................................................................................................5 3.1 Die Anmeldung........................................................................................................6 3.1.1 Der direkte Weg zum Server..............................................................................6 3.1.2 Mit dem Broadcast zum Server..........................................................................8 3.2 Die Vorbereitungen vor dem Spiel Organisation................................................17 3.3 Das Protokoll.........................................................................................................19 3.3.1 Der erste Kontakt.............................................................................................20 3.3.2 Das Spiel..........................................................................................................20 3.3.3 Die Ergebnisse.................................................................................................22 4 Schluss.........................................................................................................................23 5 Literaturverzeichnis.....................................................................................................24 6 Abbildungsverzeichnis.................................................................................................24 7 Anhang.........................................................................................................................25 7.1 UML Diagramm..................................................................................................25

-2-

-3-

1 Einleitung
Ich werde mich in dieser Facharbeit mit einem Wettbewerbs- und Rankingsystem auf Netzwerkbasis anhand von Othello befassen. Prziser formuliert handelt es sich um ein Client-Server System, das die einzelnen Spiele aller Beteiligten organisiert, durchfhrt und auswertet. Der Anwendungsbereich knnte hierbei z.B. bei einem Wettbewerb fr Schachcomputer oder bei meinem Beispiel Othelloturnier liegen. Dabei wird besonderer Wert auf die Kommunikation und Verwaltung in JAVA in der Version 6 gelegt. Das heit Ziel wird die Entwicklung und die genaue Erluterung des Netzwerkprotokolls, sowie die Organisation der Clients im Server und der Datenerhebung fr die Auswertung und Bewertung aller Clients sein. Der Client wird eine untergeordnete Rolle spielen und in groen Stcken als gegeben betrachtet, soweit dies nicht zum allgemeinen Verstndnis notwendig sein sollte. Die Facharbeit wird zunchst die Grundzge des Spielablaufes klren, um anschlieend Aufbau und genaue Realisierung des Servers zu beschreiben, wobei auf Probleme bei der Programmierung der einzelnen Aufgabenbereiche hingewiesen wird.

2 Othello
In diesem Kapitel mchte ich eine kurze Einfhrung zu dem 1971 aus Reversi hervorgegangenem Spiel Othello geben und den Aufbau, sowie die Spielregeln und den Spielverlauf im Allgemeinen klren. Auerdem werden einige Besonderheiten an konkreten Spielsituationen erklrt.

2.1 Aufbau und Spielregeln


Das Spielfeld besteht aus einem 8x8 Felder messendem Brett (z.B Schachbrett). Gespielt wird mit zwei Spielern und Spielsteinen in zwei Farben. Das heit eine Seite eines Spielsteins ist schwarz, die andere Seite wei. Jedem Spieler wird eine Farbe zugewiesen.

-3-

-4Zu Beginn wird das Spielfeld in folgender Weise vorbereitet: Die mittleren vier Felder (D4,E4,D5,E5) werden nach1 nebenstehendem Muster besetzt und der Startspieler, derjenige der den ersten Zug vornimmt, wird bestimmt. Aus historischen Grnden wird normalerweise der Spieler mit der schwarzen Farbe als Startspieler erklrt.

Es wird abwechselnd gezogen. Der aktive Spieler (der Spieler, der am Zug ist) setzt einen Spielstein in seiner Farbe auf ein leeres Feld, das horizontal, vertikal oder diagonal an ein bereits besetztes Feld grenzt. Die Farbe des angrenzenden Spielsteins spielt hierbei keine Rolle. Auerdem muss es, damit der Zug gltig ist, zum Umdrehen mindestens eines gegnerischen Steins kommen. Zum Umdrehen eines gegnerischen Steins kommt es immer dann, wenn zwischen dem neu gelegten Stein und einem oder mehreren bereits liegenden Stein(en) der selben Farbe ausschlielich Steine der anderen Farbe liegen. Dazwischen bedeutet in einer geraden Linie, die horizontal, vertikal oder diagonal verlaufen kann, ohne dass ein Stein der eigenen Farbe vorkommt. Ist ein solch gltiger Zug nicht mglich, muss der Spieler aussetzen und der andere Spieler ist am Zug.

Ziel des Spiels ist es, so viele Steine in seiner Farbe auf dem Feld liegen zu haben wie mglich. Das Spiel endet, wenn das komplette Spielfeld besetzt ist oder beide Spieler keinen gltigen Zug mehr vornehmen knnen.

2.2 Beispiele fr Spielsituationen


2

Wei setzt auf D3 einen neuen

Stein und erhlt dadurch die vertikale und diagonale Reihe dazu (E4,D4,D5).
1 http://de.wikipedia.org/wiki/Othello_%28Spiel%29 (20.03.2012) 2 http://de.wikipedia.org/wiki/Othello_%28Spiel%29 (20.03.2012)

-4-

-5In der folgenden Spielsituation ist Wei am Zug. Da aber alle noch mglichen Spielzge dazu fhren, dass kein gegnerischer Stein umgedreht wird, muss Wei seinen Zug aussetzen und Schwarz ist am Zug.

In dem Fall, dass auch Schwarz wiederum nicht gltig

setzen kann, wre das Spiel an diesem Punkt vorbei, und es wrde die Auswertung folgen. Angenommen, dies wre die endgltige Situation, htte Schwarz 16 Punkte und somit gegen Wei (15 Punkte) gewonnen.

3 Der Server
Dieses Kapitel stellt den Hauptteil der Arbeit dar und wird sich mit der serverseitigen Realisierung des Wettbewerbssystems beschftigen. Das Prinzip des Servers hat man sich folgenderweise vorzustellen: Die Teilnehmer (Clients) des Othelloturniers mssen sich beim Server anmelden. Dieser nimmt die Teilnehmer in einer vom Spielleiter vorgegebenen Zeit an und trgt sie mit Name und sonstigen zur Identifizierung ntigen Daten (z.B. E-Mail Adresse) in seine Liste ein. Nachdem die Zeit zur Anmeldung abgelaufen ist, nimmt der Server keine weiteren Teilnehmer mehr an und kmmert sich im nchsten Schritt um die Austragung des Wettbewerbs. Der Wettbewerb soll so gestaltet sein, dass jeder gegen jeden zwei Mal antritt (Farbwechsel Wechsel des Startspielers) und der Gewinner durch die Anzahl der gewonnen, verlorenen oder unentschieden gespielten Spiele ermittelt wird. Der Server hat hierbei die Aufgabe dafr zu sorgen, dass die Kommunikation mit den Teilnehmern funktioniert und die Spielregeln eingehalten werden. Dazu muss der Server die Regeln des Spiels genauso gut kennen wie die Teilnehmer. Abschlieend ist der Server dafr zustndig die Spielergebnisse zu notieren und fr die anschlieende Auswertung bzw. Archivierung zu speichern. Zur Bewltigung dieser Aufgaben wird der Server in entsprechende Aufgabenbereiche unterteilt. Im Zuge der Umsetzung der Aufgabenbereiche werden
3 http://de.wikipedia.org/wiki/Othello_%28Spiel%29 (20.03.2012)

-5-

-6Hilfsklassen und Multithreading notwendig. Im Folgenden werde ich mglichst chronologisch die Umsetzung der genannten Aufgabenbereiche erlutern.

3.1 Die Anmeldung


Dieses Kapitel wird sich mit dem Weg vom Client zum Server befassen. Zum einen wird der direkte Weg ber eine TCP/IP Verbindung behandelt. Andererseits wird auf die Mglichkeit eingegangen, alle relevanten Server im Netzwerk mit Hilfe eines Broadcasts automatisiert zu finden.

3.1.1 Der direkte Weg zum Server


Um die Clients annehmen zu knnen, muss zunchst der Server initialisiert und auf das Annehmen vorbereitet werden. Dies wird durch folgenden Programmcode erreicht:
public void startAcceptClients(String ip, int port) throws IOException{ stopAcceptClients(); server=new ServerSocket(); server.setSoTimeout(5000); server.bind(new InetSocketAddress(ip,port)); acceptthread=new AcceptThread(); } public void stopAcceptClients(){ if(acceptthread!=null){ acceptthread.stop(); acceptthread=null; } } private class AcceptThread{ volatile boolean run=false; Thread t; public AcceptThread(){ run=true;

-6-

-7t= new Thread(new Runnable(){ @Override public void run() { while(run){ try { Socket client = server.accept(); } catch (IOException e) { e.printStackTrace(); } } }}); t.start(); } public void stop(){ run=false; t=null; } }

Zunchst wird die Methode startAcceptClients(String ip, int port) aufgerufen, die den ServerSocket erzeugt und an die mitgegebene IP-Adresse und den Port bindet. stopAcceptClients(); wird aufgerufen um zu verhindern, dass ein neuer Thread erstellt wird, ohne dass ein potentiell noch vorhandener AcceptThread sachgem beendet wurde und unter Umstnden ewig weiterlaufen wrde. Die eigentliche Annahme geschieht innerhalb von AcceptThread solange dieser Thread nicht wieder gestoppt wird werden hier die Clients mit server.accept(); angenommen. Da diese Methode allerdings blockiert, bis ein Client angenommen wurde, muss dem ServerSocket ein Timeout zugewiesen werden, welches dafr sorgt, dass der Versuch, einen neuen Client anzunehmen, alle 5 Sekunden gestoppt wird. Wichtig in dem Thread ist, dass der boolean run als volatile bezeichnet wird. Da diese Variable regelt, wie lange der Thread lebendig ist und von zwei oder mehreren Threads verwendet wird, muss hierdurch erwirkt werden, dass alle Threads von mglichen nderungen an der Variable informiert werden4.

4 Thomas Knneth 2011, S.151 und Christian Ullenboom 2012, 11.7 Client-Server-Kommunikation

-7-

-8-

3.1.2 Mit dem Broadcast zum Server


Die Idee hinter einem Broadcast ist es, alle erreichbaren Computer zu befragen, ob die gesuchte Funktionalitt dort zur Verfgung steht. Dazu wird ein UDP-Paket an alle Computer innerhalb des lokalen Netzwerks gesendet. Dieses Paket enthlt Informationen darber, was der Client, der dieses Paket versendet, wissen mchte und von wem er diese Information bekommen will. Wenn ein passender Server dieses Paket empfngt stellt er dem Client die geforderten Informationen zur Verfgung. Die folgende Grafik soll dies noch einmal verdeutlichen:

Im Detail betrachtet muss in Java ein DatagramPacket und ein DatagramSocket erzeugt werden. Das DatagramSocket ist fr den Versand des UDP-Paketes verantwortlich, sowie fr den Empfang der mglichen Antworten. Damit aus dem ganzen ein Broadcast -8-

-9wird, ist es notwendig


DatagramSocket.setBroadcast(true);

aufzurufen und als IP-

Adresse die 255.255.255.255 anzugeben. Jetzt wird das Paket an alle empfangsfhigen Computer im Netzwerk gesendet. Dieses Verfahren ist als Limited Broadcast bekannt. In dem folgenden Quellcode wird allerdings auf den Directed Broadcast zurckgegriffen, der etwas mehr Kontrolle erlaubt. Da es auch innerhalb des erreichbaren Netzes Unterteilungen gibt, kann somit eine genaue Ansteuerung eines dieser Unternetze erzielt werden. Der einzige Unterschied zum Limited Broadcast liegt bei der IP-Adresse. Diese wird aus einer Kombination des Zielnetzes und der Netzmaske gebildet. Sei die eigene IP-Adresse 192.168.100.102 und die Netzmaske 255.255.255.0 so ist die Broadcast IP-Adresse 192.168.100.255. Das heit alle Stellen der eigenen IP werden bernommen, wenn die Netzmaske an dieser Stelle den Wert 255 hat ansonsten wird diese Stelle der Broadcast IP-Adresse mit 255 gefllt 5. Die Adresse wird durch die Kombination aus Zielnetz und dem Setzen aller Hostbits auf 1 angegeben6 (Wikipedia - Broadcast).

Damit der Server, der das Paket empfangen soll wei, dass dieses Paket von einem Othello Client stammt, wird dem Paket als Datenteil z.B ein Text (Ich bin es Othello) hinzugefgt.

Sobald der Server das Paket angenommen und als relevant erkannt hat, schickt dieser ein neues Paket zurck an den Client, sodass dieser, wie auch der Server, ber
DatagramPacket.getAddress()

und

DatagramPacket.getPort()

die

notwendigen

Verbindungsdaten erfragen kann. Auf diesem Weg muss ausschlielich der Port bekannt sein, an den der Broadcast gesendet wird, um alle Server zu finden, die in Frage kommen, um sich mit ihnen zu verbinden. In Quelltext sieht das ganze dann wie folgt aus (Fortsetzung des Textteils ab S.17):

Serverseite:
5 aus diesem Grund kann auch kein Rechner eine IP mit einer 255 haben 6 http://de.wikipedia.org/wiki/Broadcast (20.03.2012)

-9-

- 10 private DatagramSocket socket private int wird private Server server = null; // interne Serverinstanz = null; // Serverinfos listeners = new port = null; // Socket fr die Datagramme = 0; // Der Port, der verwendet

private DatagramPacket serverInfo private Vector<FindServersListener>

Vector<FindServersListener>(1,1); // FindServersListeners verwalten private int BUFFERSIZE = 1024;

public int getPort() { return port; } public FindServer(int port,int Bufsize,final String stdserverinfo)throws IllegalArgumentException, SocketException{ if (port < 1 || port > 65535){ throw new IllegalArgumentException ("Port number is out of range!");} this.port=port; try { socket = new DatagramSocket (port); // zum Testen, ob der Port geht socket.close(); setServerInfo (stdserverinfo); // StandardServerInfo startServer(); } catch (SocketException e) { throw new SocketException ("Can't bind to specified Socket!"); } this.BUFFERSIZE=Bufsize; } /** * Servernachricht setzen. * */ public void setServerInfo (String str) {

- 10 -

- 11 -

if (str==null) str=""; byte buf [] = str.getBytes(); if (serverInfo!=null) { synchronized (serverInfo) { serverInfo = new DatagramPacket (buf, buf.length); } } else } { serverInfo = new DatagramPacket (buf, buf.length); }

/** * Den Server starten. * */ public void startServer () {

if (server!=null) return; // Einfach ignorieren try { socket = new DatagramSocket(port); } catch (SocketException e) { } server = new Server(); server.start(); } /** * Den Server stoppen. * */ public void stopServer () {

if (server==null) return; // Einfach ignorieren socket.close(); server=null; socket=null; } /**

- 11 -

- 12 * Testen, ob ein Server l&uft. * */ public boolean isServerRunning () { return server!=null; } public void addFindServerListener(FindServersListener c){ listeners.add(c); }

/** * Interne Klasse Server dient zum Beantworten von Anfragen der Clients. */ private class Server extends Thread { public void run () { while (server!=null) { try { byte[] inbuf = new byte[BUFFERSIZE]; DatagramPacket in = new DatagramPacket(inbuf, inbuf.length); socket.receive(in); boolean send=true; for (int i=0; i<listeners.size(); i++) {

send=((FindServersListener)listeners.get(i)).clientRequest(FindServer.this,i n); } if(send){ serverInfo.setAddress(in.getAddress()); serverInfo.setPort(in.getPort()); synchronized (serverInfo) { socket.send(serverInfo); } }

- 12 -

- 13 -

} catch (IOException e) { } } } }

Clientseite:
private DatagramSocket socket private int wird private int timeout = 1000; // Timeout frs receivedDatagramPackets = new private Vector<DatagramPacket> Vector<DatagramPacket>(10,1); / private int BUFFERSIZE = 1024; port = null; // Socket fr die Datagramme = 0; // Der Port, der verwendet

public FindClient(int port,int Bufsize)throws IllegalArgumentException, SocketException{ if (port < 1 || port > 65535){ throw new IllegalArgumentException ("Port number is out of range!");} this.port=port; try { socket = new DatagramSocket (port); // zum Testen, ob der Port geht socket.close(); } catch (SocketException e) { throw new SocketException ("Can't bind to specified Socket!"); } this.BUFFERSIZE=Bufsize; } /** * Timeout fr das Anpingen setzen.

- 13 -

- 14 * */ public void setTimeout (int timeout) throws IllegalArgumentException {

if (timeout < 0) throw new IllegalArgumentException ("No negative timeout allowed!"); this.timeout=timeout; } /** * Server anpingen. * */ public boolean requestServerInfos (DatagramPacket dp) { receivedDatagramPackets.clear(); try { InetAddress ownIP = InetAddress.getLocalHost(); InetAddress broadcastIP = getBroadcastAddress(ownIP); dp.setAddress(broadcastIP); dp.setPort(port); socket = new DatagramSocket (port); socket.send(dp); socket.close(); socket = new DatagramSocket (port); socket.setSoTimeout(timeout); while (true) { try { byte buf [] = new byte[BUFFERSIZE]; dp = new DatagramPacket(buf, buf.length); socket.receive(dp); receivedDatagramPackets.add(dp); } catch (SocketTimeoutException e) { break; } } socket.close();

- 14 -

- 15 } catch (IOException e) { e.printStackTrace(); } return (!receivedDatagramPackets.isEmpty()); }

/** * Serverinfos holen. * */ public DatagramPacket [] getServerInfos () {

return (DatagramPacket [])receivedDatagramPackets.toArray(new DatagramPacket[0]); } /** * Server anpingen. * */ public boolean requestServerInfos (DatagramPacket dp,InetAddress broadcastIP) { receivedDatagramPackets.clear(); try { dp.setAddress(broadcastIP); dp.setPort(port); socket = new DatagramSocket (port); socket.send(dp); socket.close(); socket = new DatagramSocket (port); socket.setSoTimeout(timeout); while (true) { try { byte buf [] = new byte[BUFFERSIZE]; dp = new DatagramPacket(buf, buf.length);

- 15 -

- 16 socket.receive(dp); receivedDatagramPackets.add(dp); } catch (SocketTimeoutException e) { break; } } socket.close(); } catch (IOException e) { } return (!receivedDatagramPackets.isEmpty()); }

/** * Server anpingen. * */ public boolean requestServerInfos (String str) { if (str==null) str=""; byte buf [] = str.getBytes(); DatagramPacket dp = new DatagramPacket (buf,buf.length); return requestServerInfos(dp); } public String getBroadcastAddressS(InetAddress address) throws UnknownHostException{

return getBroadcastAddress (address).getHostAddress(); } /** * anders als im Text wird hier die Broadcast Adresse selbst ermittelt und nicht ber .setBroadcast(true) Java berlassen * */ public InetAddress getBroadcastAddress (InetAddress address) throws UnknownHostException { byte ipBytes [] = address.getAddress();

- 16 -

- 17 if (ipBytes[0]<(byte)128) ipBytes[1]=(byte)255; if (ipBytes[0]<(byte)192) ipBytes[2]=(byte)255; ipBytes[3]=(byte)255; return InetAddress.getByAddress(ipBytes); }

3.2 Die Vorbereitungen vor dem Spiel Organisation


Ist ein Client erst einmal angenommen, muss dieser in irgend einer Weise gespeichert und mit allen anderen zusammen organisiert werden, bevor das Spielen los gehen kann.

Client

verbindet sich

Server
Annahme und erster Kontakt

Organisator

Teilnehmer

Trennung bei Fehlern

Sammeln im Pool bei erfolgreicher Annahme

Keine weiteren Annahmen Erstellung und Ausfhrung aller Spiele

GUI

Sind alle Spiele fertig: Ausgabe der Ergebnisse

Games

Sobald der Client angenommen und akzeptiert wurde, sorgt der Organisator dafr, dass - 17 -

- 18 alle Teilnehmer einheitlich an einem Ort gesammelt werden. Da im Verlauf des Programms fter Zugriffe auf bestimmte und unbestimmte bzw. alle Teilnehmer erfolgen, wird fr diesen Ort ein Vector verwand. Da der Vector, der im Prinzip eine doppelt verkettete Liste ist, wahlfreien Zugriff gewhrt, d.h. direkter Zugriff auf ein Element, ist er die beste zur Verfgung stehende Datenstruktur. Dem zu Gute kommt die Mglichkeit ohne zustzliche Arbeit durch den Vector iterieren zu knnen. Damit alle Clients gleichzeitig die Chance haben mit dem Server zu kommunizieren, wird jeder Teilnehmer in einem eigenen Thread ausgefhrt. Whrend des ersten Schritts findet bereits die erste Kommunikation statt. Der Server informiert sich ber den Namen des Clients und weist diesem einen eindeutigen Identifikationsstring(ID) zu 7. Da sich mehrere Clients von einem realen Computer anmelden knnen mssen, ist der manchmal praktizierte Weg, die IP als ID zu verwenden, nicht mglich.

Dieser Vorgang wird fortgefhrt, bis der Server keine Teilnehmer mehr akzeptiert. Sei es, weil der Speicher voll ist, oder weil der Spielleiter (Serveradministrator) keine weiteren Teilnehmer mehr haben mchte. Ab jetzt sorgt der Organisator dafr, dass alle Spiele (Games) erzeugt werden. Das heit, es werden fr jedes Spielpaar zwei Objekte (Hin- und Rckrunde) der Klasse Game erzeugt, die ihrerseits alle bentigten Informationen fr dieses eine Spiel verwaltet. So z.B. die beiden Teilnehmer, das Spielfeld, den Punktestand und die Kommunikation zwischen den Spielern.

Sobald alle Spiele beendet sind werden die Ergebnisse ausgewertet. Dazu gehren auch Verste gegen die Spielregeln. Schlielich werden die so eben erstellten Daten ber die Server-GUI dem User angezeigt. Es wre auerdem mglich den Clients die Ergebnisse mitzuteilen. Da es hier aber um ein lokales Netzwerk handelt, wird kaum eine so groe rumliche Distanz existieren, dass dies ntig wird (Ein mglicher Vorschlag zur Realisierung folgt).

7 Fr genauere Beschreibung siehe Das Protokoll

- 18 -

- 19 -

3.3 Das Protokoll


Dieses Kapitel beschftigt sich mit der konkreten Ausfhrung eines Spiels aus Sicht der Netzwerkebene. Bei der Kommunikation wird auf ein textbasiertes Befehlsprotokoll gesetzt, das dem Interaktionsmodell der synchronen Kommunikation folgt (vgl. Dietmar Abts 2007, S. 9). Das bedeutet, dass jede Anfrage erst eine Antwort bekommen muss, bevor das Programm bzw. der jeweilige Thread weiterarbeiten kann. Da es fr die Kommunikation wichtig ist, dass alles und in der richtigen Reihenfolge bei dem Partner ankommt, benutze ich eine TCP/IP Verbindung. Diese wird auerdem, solange kein Fehler auftritt, whrend des gesamten Lebenszyklus des Programms nicht unterbrochen. Der Eingabe, sowie der Ausgabestrom werden aufgrund der textbasierten Kommunikation in ein BufferedReader bzw. ein BufferedWriter geschachtelt. Somit muss jeder Befehl als eindeutiger String der Form Befehl:Parameter<;>Parameter versendet werden. Die Parameter sind je nach Befehl optional oder nicht zulssig. Die einzigen dringend notwendigen einzuhaltenden Konventionen sind, dass auf beiden Seiten, d.h. Server und Client, die gleiche Zeichencodierung und der gleiche Aufbau fr einen Befehl verwendet werden muss. So wird in diesem Beispiel UTF-8 benutzt, da durch JAVA im Gegensatz zu UTF-8 nicht notwendigerweise alle Zeichencodierungen auf allen Plattformen untersttzt werden (vgl. Dietmar Abts 2007, S. 115 ff.).

Sind diese Grundvoraussetzungen gegeben, muss allen Beteiligten nur noch eine gemeinsame Sprache, das Protokoll bekannt sein, nachdem die einzelnen Befehle ihre Bedeutung erhalten. Wenn der Server den Befehl zum Trennen der Verbindung mit SHUTDOWN sendet, versteht der Client nicht was von ihm gewollt wird, wenn in seinem Protokoll GEHNACHHAUSE fr diese Aufgabe vermerkt ist. So hat jede Aufgabe ihren eigenen Befehl. Im Grunde kann so ein fr jeden Menschen und Computer verstndliches Protokoll erzeugt werden, das Zugriff auf alle Funktionen gewhrleisten kann. Im folgenden wird dieses Vorgehen in der Kommunikation anhand des zu behandelnden Othello-Server erlutert.

- 19 -

- 20 -

3.3.1 Der erste Kontakt


Wurde der Client vom Server akzeptiert/angenommen, wird ab sofort in regelmigen Abstnden ein einfacher Befehl (PING) versendet, um die Verbindung aufrecht zu erhalten und von einem mglichen Verbindungsverlust informiert zu werden. Sollte die Verbindung abbrechen, bekommt dies der Server in JAVA erst mit, wenn der Client auf die bestehende Verbindung geprft wird.

Weiter werden alle bentigten Identifikationsinformationen vom Client zugesandt. So wird der Name des Spielers bermittelt und die Uhrzeit mit
System.currentTimeMillis()

erfragt und an den Namen angehngt, damit dieser Name

als eindeutige ID genutzt werden kann. Auerdem fordert der Server den Client auf, sich auf die Spiele vorzubereiten und informiert den Client damit gleichzeitig darber, dass mglicherweise eine lngere Wartephase beginnt, bis keine Clients mehr angenommen werden und die Spiele beginnen.

Client NAME:maxmustermann PREPAREGAME

Server

PING (immer wiederholen)

3.3.2 Das Spiel


Sobald der Server die Spiele eingeleitet hat, erstellt dieser einen Spielplan und sorgt dafr, dass alle Spiele ausgetragen werden. Sollte die Verbindung zu einem der Spieler abbrechen oder dieser einen nicht gltigen Zug ausfhren, wird dies als Niederlage gewertet und seine Spielpunkte werden auf -1 gesetzt.

Der regulre Spielablauf sieht zunchst vor, dass alle Beteiligten eines Spiels ber ihre Farbe, sowie den Startspieler informiert werden. Auerdem werden die Clients aufgefordert das Spielfeld vorzubereiten. Ich habe mich in meinem Protokoll dazu - 20 -

- 21 entschieden, dass jeder Client sein eigenes Spielfeld verwaltet und nur ber die vorgenommenen Zge informiert wird, um unntigen Datenverkehr zu vermeiden, da der Prozessor weniger Zeit fr die zustzlichen Berechnungen bentigt, als es das Versenden des ganzen Spielfeldes kosten wrde. Es kann allerdings auch die Mglichkeit implementiert werden, dass der Client das momentane Spielfeld abfragen kann, sollte dieser es fr ntig halten. Anschlieend wird, wie traditionell geregelt, der erste Spieler, der Schwarze, nach seinem Zug befragt.

Ab diesem Zeitpunkt werden die folgenden Aktionen bis zum Spielende immer wieder ausgefhrt: Der Server wartet auf den Zug des ersten Spielers und berprft ihn auf Gltigkeit. Sollte der Zug ungltig sein, wird dies als Fehler gewertet und der Spieler hat verloren. Ist dies nicht der Fall, wird der zweite Teilnehmer ber den Zug informiert und der Server fhrt diesen Zug selbstredend auch auf seinem Spielfeld aus, sowie jeden anderen gltigen Zug.

Nun berprft der Server, ob der zweite Spieler berhaupt in der Lage ist einen gltigen Zug zu ttigen. Sollte ein solcher Zug mglich sein, wird nun der zweite Spieler aufgefordert seinen Zug durchzufhren. Auch hier wird der Zug geprft, bernommen und an den anderen Spieler geschickt.

Sollte nun wiederum der erste Spieler in der Lage sein einen Zug zu ttigen, wird dieser erneut aufgefordert zu ziehen. Kann dieser allerdings nicht ziehen, wird berprft , ob berhaupt ein Spieler einen Zug durchfhren kann. Sollte dies so sein, wird der zweite Spieler solange aufgefordert zu ziehen, bis der erste Spieler wieder einen gltigen Zug erwirken kann. Sollte keiner der beiden Spieler einen Zug ausfhren knnen, ist das Spiel vorbei und beiden Spielern wird das Spielende mitgeteilt.

- 21 -

- 22 Client Server C1 COLOR:BLACK C2 COLOR:WHITE PREPAREPLAYGROUND C1 DOTURN Wiederholung C1 TURN:x<;>y C2 TURNDONE:x<;>y C2 DOTURN C2 TURN:x<;>y C1 TURNDONE:x<;>y C1 DOTURN Wiederholung GAMEOVER Wiederholung Wiederholung

3.3.3 Die Ergebnisse


Sobald alle Spiele fertig sind, also den GAMEOVER Status erreicht haben, wertet der Server die gesammelten Ergebnisse aus. Dabei wird ein Sieg mit drei Punkten belohnt und ein Unentschieden mit einem Punkt. Einen Niederlage ndert die Punkte in keiner Weise. Sollten zwei Spieler die gleiche Punktzahl haben, entscheidet das Punkteverhltnis zwischen Schwarzen und Weien Steinen innerhalb der einzelnen Spiele. Haben zwei Spieler gleiche Punkte und z.B. in allen Spielen zusammen ein Verhltnis von eigenen zu gegnerischen Steinen von 1.5 und 1.7 so hat der Spieler mit dem Verhltnis von 1.7 gewonnen.

Dieses Ranking wird auf der Serverseite innerhalb einer GUI angezeigt und den Clients bermittelt. Das bermitteln findet in der Form statt, dass der Server mitteilt, dass die Rankingtabelle folgt und von bestem zu schlechtesten alle Spieler bermittelt. Client RANKINGTABLE PLAYER:Name<;>Punkte<;>Eigene Steine<;>Gegnerische Steine - 22 Server

- 23 Es wre mglich noch weitere Informationen zu sammeln. So zum Beispiel die Dauer der Spiele oder das Spielverhalten. Doch soll hierauf keine Rcksicht genommen werden, da sich dadurch keinerlei nderung fr das Vorgehen entsteht.

4 Schluss
Abschlieend mchte ich noch einmal auf die Vielschichtigkeit eines Servers hinweisen. In meinem Beispiel ist der Server in Annahme der Clients, deren Verwaltung, die Ausfhrung der Spiele und das dazu gehrende Protokoll zu unterteilen. Wichtig ist fr den reibungslosen Ablauf einer Kommunikation ber TCP/IP eine einheitliche Zeichencodierung und ein fr beide Seiten bekanntes Protokoll. Das dazu gehrende Programm, sowie der Quelltext sind auf der digitalen Version dieser Facharbeit zu finden.

- 23 -

- 24 -

5 Literaturverzeichnis
Abts, Dietmar. Masterkurs Client/Server-Programmierung mit Java. Wiesbaden 2007: Friedr. Vieweg & Sohn Verlag | GWV Fachverlag GmbH April 2007 (2., erweiterte und aktualisierte Auflage) Knneth, Thomas. Android 3. Apps entwickeln mit dem Android SDK. Bonn 2011: Galileo Press (1.Auflage 2011 1. korrigierter Nachdruck 2012) Ullenboom, Christian: Java ist auch eine Insel. Das umfassende Handbuch, Galileo Press. 10.Auflage. Onlineausgabe (aufgerufen 25.03.2012) Ullenboom, Christian. Java 7 - Mehr als eine Insel. Das Handbuch zu den Java SE-Bibliotheken. Galileo Press. Onlineausgabe (Stand 25.03.2012) Wikipedia. Othello (Spiel) [online]. Update: 18. Februar 2012 um 00:16 Uhr. URL:<http://de.wikipedia.org/wiki/Othello_%28Spiel%29> (Stand 21.03.2012) Wikipedia. Broadcast [online]. Update: 10. Mrz 2012 um 10:20 Uhr. URL:<http://de.wikipedia.org/wiki/Broadcast> (Stand 21.03.2012)

6 Abbildungsverzeichnis

Zu finden auf Seiten 4 und 5. Alle Spielfelder sind als Vorlage Wikipedia. Othello (Spiel) [online] entnommen

- 24 -

- 25 -

7 Anhang

7.1 UML Diagramm

- 25 -

- 26 -

- 26 -

- 27 -

- 27 -

- 28 -

- 28 -

- 29 -

- 29 -

- 30 -

- 30 -