Skip to content

Instantly share code, notes, and snippets.

@jonasschneider
Created November 15, 2013 17:09
Show Gist options
  • Save jonasschneider/7487947 to your computer and use it in GitHub Desktop.
Save jonasschneider/7487947 to your computer and use it in GitHub Desktop.
Praktikum Protocol Engineering WS 2013/2014
Aufgabenblatt
Jonas Schneider <[email protected]>
Gruppe 3
Ausgabe: 05.11.2013, Abgabe: 15.11.2013, 12:00
1 Prototypischer Protokollentwurf
=================================
(Ich werde der Einfachheit halber den Indikativ verwenden, auch wenn natürlich
noch nichts fest steht.)
Das Protokoll ist aufgeteilt in zwei voneinander unabhängige Unterprotokolle:
das Lobby-Protokoll und das Spiel-Protokoll. Diese verwenden beide die gleiche
Syntax, haben jedoch unterschiedliche Befehlstypen.
Das Protokoll ist TCP- und zeilenbasiert, prinzipiell ähnlich zu SMTP und
anderen Protokollen der Ära. Jede Zeile ist in Befehl (in Großbuchstaben) und
Argumente (eine Liste von ""-umgebenen Strings) unterteilt. Die Identität der
Verbindung ist ein Teil des Protokollzustandes, d.h. Redundanz soll möglichst
vermieden werden. Nitpicks: alle Daten werden als UTF-8 kodiert,
Zeilenumbrüche sind LF (U+000A).
Im Folgenden bezeichne ">" Nachrichten von Client zu Server und "<"
Nachrichten von Server zu Client. Alle Nachrichten beider Parteien sind genau
einzeilig. Auf jede Anfrage des Clients folgt genau eine Antwort des Servers.
Zur Synchronisation (z.B. bei READY) wird die Verbindung blockiert, der Client
pollt nicht und der Server pusht auch nicht ungefragt. (Wichtige Beschränkung
-- macht manche Features wie z.B. Chat schwierig, aber das grundlegende
Protokolldesign wesentlich einfacher.)
Spielprotokoll
--------------
Jeder Mitspieler öffnet als Client eine TCP-Verbindung zum Server (wohin genau
er verbindet, erfährt er durch das unten erklärte Lobbyprotokoll.) Ein
typischer Ablauf könnte so aussehen:
> HELLO "jonasschneider"
< OK "Welcome jonasschneider"
> READY
(warten bis Mitspieler ebenfalls bereit)
< STATE "<token>" "<board>"
> MOVE <spalte>
(warten bis Mitspieler Zug eingibt; Zug wird ausgeführt)
< STATE "<token>" "<board>"
(weitere Züge..)
> MOVE "5"
< END "<winner>"
Dabei sei <token> ein Indikator für den Besitzer des Initiativtokens,
z.b. "1" für Spieler 1 und "2" für Spieler 2.
Dabei sei <board> eine geeignete Kodierung des Spielfeldes. Beispielsweise
bietet sich an, z.B. ein 3x3-Spielfeld, bei dem Spieler 1 in jede Spalte einen
Spielstein eingeworfen hat (wie auch immer das gehen mag), als "1 1 1" zu
modellieren. Wirft nun Spieler 2 in die zweite Spalte einen Spielstein ein,
ändert sich die Kodierung zu "1 12 1", die Kodierung ist also von links nach
rechts und von unten nach oben. Weggelassene Felder sind implizit unbelegt,
die "leere Spalte" wird durch "-" oder eben "" kodiert.
Befehlstypen: (Client -> Server)
- HELLO (Begrüßung, Übertragung Spielername)
- READY (Anzeige, dass bereit für den Beginn der Partie)
- MOVE (Eingabe eines Zuges)
- QUIT (Trennung der Verbindung)
Antworttypen: (Server -> Client)
- OK (generisch; mit Nachricht)
- STATE (enthält Partiezustand der laufenden Partie)
- END (informiert über Partieende)
- ERR (generisch; mit Fehlermeldung) -- tritt während der Bearbeitung ein
Fehler auf, wird ERR geantwortet. Der Client kann dann davon ausgehen, dass
sich der Zustand auf dem Server nicht verändert hat. Ist dies nicht
gewährleistbar, liegt ein fataler Fehler vor.
Eine Partie hat die folgenden Zustände:
1. "leer; niemand ist verbunden" (Startzustand)
2. "ein Spieler verbunden"
3a. "warte auf Eingabe der Züge beider Spieler"
3b. "warte auf Eingabe der Züge von Spieler A"
3c. "warte auf Eingabe der Züge von Spieler B"
4. "regulär vorbei, Gewinner <X>"
5. "irregulär vorbei, <Grund>"
Einige (nicht alle Zustandsübergänge):
1. -> 2.: erster Spieler verbindet
2. -> 3a.: zweiter Spieler verbindet
3a -> 3b.: erster Spieler gibt Zug ein
3b -> 3a.: zweiter Spieler gibt Zug ein
3b/c -> 4: ein Spieler macht gewinnenden Zug
3a/b/c -> 5: Verbindung eines Spielers bricht ab
Lobbyprotokoll
--------------
Das Lobbyprotokoll dient der Auflistung der laufenden Spielpartien und der
Erstellung neuer Partien.
> HELLO "jonasschneider"
< WELCOME "jonasschneider"
> LIST
< GAMES "10.10.10.10:95001 go game pls fast noobz only"
> CREATE "jonasschneider"
< OK "10.10.10.10:95002"
Zum Beitreten zum Spiel verbinden sich die Spieler zum angegebenen TCP-Port.
Der Server listet genau die Partien im Zustand "warte auf Verbindung des
Gegenspielers" auf. Jede Partie hat einen Namen; der Einfachheit halber können
Clients standardmäßig den Spielernamen des erstellenden Spielers angeben,
solange kein expliziter eigener Name gewünscht ist.
2 Interface Design
==================
Das Interface wird konsolenbasiert sein (ncurses o.Ä.). Das folgende Mockup
ist ASCII, aber die ANSI- und Unicode-Rahmen sollten ebenfalls verwendbar
sein. Die Spielansicht zeigt das Spielbrett und weitere Informationen:
(Welcher Spiele welchen Steintyp hat, sollte Konvention sein oder anstatt der
Pfeile angezeigt werden.)
------------------------------------------------------------------
| ↓↓ |
| | | | | | | | | | vs: florianjacob |
| | | | | | | | | | Zeit: 1:17 |
| | | | | | | | | | Zug: 5 |
| | | | | | | | | | |
| | |XX| | | | | | | |
| | |XX| | | | | | | |
| |XX|++| | | | | | | |
| |--|--|--|--|--|--|--|--| |
| |
------------------------------------------------------------------
Mithilfe der Pfeiltasten wird die Spalte ausgewählt, in die der Spieler seinen
nächsten Spielstein werfen will. Mit Enter wird diese Eingabe bestätigt. Das
Interface geht dann in den Wartezustand über, bis der Gegner den nächsten Zug
ebenfalls eingegeben hat. Dann wird das Spielfeld aktualisiert. (Bis zur
Aktualisierung kann der neu eingeworfene Stein vom Client simuliert werden,
falls sich das als sinnvoll ergibt.)
Zustände des Interfaces:
1 Willkommensbildschirm / Lobby / Liste von Partien (Verbinden -> 2a)
2 Partie-Ansicht (Bild s.o.)
2a Verbinden zum Server (Abbruch -> 1)
2b Warten auf Verbindung des Mitspielers (Abbruch -> 1)
2c Zugeingabe (Zug -> 2d)
2d Warten auf Zug des Mitspielers (Daten empfangen -> 2c, Spiel vorbei -> 2e)
2e Spiel vorbei, "Du gewinnst" / "Du verlierst" (Zurück zur Lobby -> 1)
3 Entwicklungsumgebung
======================
Aus Gründen der Verständlichkeit und Wartbarkeit werden wir das Protokoll in
Java implementieren (ich persönlich hätte für dieses Problem Go gewählt). Die
Entwicklung soll jedoch nicht auf eine Entwicklungsumgebung festgelegt sein;
der Build soll vollständig durch quelloffene Software möglich sein, z.B. GNU
make. Eclipse/VisualStudio/IntelliJ-Projektdateien sollen das Verwenden der
jeweiligen Entwicklungsumgebung erleichtern.
Bibliotheken außerhalb der Java-Standardbibliothek werden nicht verwendet. Zum
Testen kann der jeweilige Kommunikationspartner durch ein `netcat` zum Testen
des Servers oder ein `netcat -l` zum Testen des Clients ersetzt werden -- die
Textbasiertheit des Protokolls erlaubt es dem Entwickler, den
Kommunikationspartner "von Hand" zu simulieren.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment