Aucune description
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

README.md 6.3KB

Homework hw9 task2

Table of Contents

1.1 Ziel

Um die bisherige Mustersuche in einem Hashwert auf mehrere Rechner auszuweiten, ist das Ziel dieser Aufgabe, einen kleinen TCP-Server zu implementieren. Die ersten Kommandos des Server haben Sie bereits in hw9:task1 implementiert.

Zuvor legen wir ein Rust Workspace an, in welchem wir komfortabel unsere eigenen Bibliotheken und ein Binary (den Server) verwalten. Nutzen Sie die in hw9:task1 geschriebene Bibliothek, in dem Sie diese als srv-commands Bibliothek in task2 benutzen, um die Kommandos an den Server zu parsen.

2.1 Aufgabe

Implementieren Sie den Webserver, in dem Sie TCPListener verwenden.

Sorgen Sie in dieser ersten Ausbaustufe dafür, dass der Server Nachrichten zwischen Anfragen speichert und in der Reihenfolge zurück gibt, in der Sie gesendet wurden. (FIFO)

Der Server darf beim Herunterfahren alle Daten verlieren. In dieser Version Ihres Servers genügt es, wenn der Server nur immer eine Anfrage zu jeder Zeit beantwortet.

2.1.1 Optionen beim Aufruf

Nun zu einer weiteren Lib im Workspace: srv-config. Diese Lib soll einen geeigneten Config Typen bereitstellen. Das Parsen und Auswerten der beim Aufruf angegebenen Parameter geschieht komplett in dieser Library. Exportiert wird nur der Config Typ und dessen Methoden (soweit nötig). Zum Parsen verwenden Sie wieder die externe Crate clap.

Multi Hash Server 0.1
M. Mächtel <maechtel@htwg-konstanz.de>
Does awesome things to find a hash with specific pattern

USAGE:
    task2 [FLAGS] [OPTIONS] [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
    -v               Sets the level of verbosity

OPTIONS:
    -a, --address <ADDRESS>    the address, where the server can be reached (127.0.0.1 is default)
    -p, --port <PORT>          the port, where the server can be reached (7878 is default)

SUBCOMMANDS:
    help    Prints this message or the help of the given subcommand(s)
    test    controls testing features

2.1.1.1 -v Option

Mit der -v Ausgabe gibt der Server folgende Informationen aus:

  • Beim Starten des Servers die Parameter, mit denen er läuft (verbose, port, address, test, …)
  • Den CONTROL-String, den der Server im CONTROL Kommando empfängt.

Benötigen Sie darüber hinaus weitere Ausgaben, so geben Sie diese bitte nur bei -vv, -vvv usw. aus.

2.1.1.2 -a Option

Mit der -a Option wird die Default Adresse: 127.0.0.1 überschrieben.

2.1.1.3 -p Option

Mit der -p Option wird der Default Port: 7878 überschrieben.

2.1.1.4 test Option

Wird diese Option mit angegeben, dann erstellt der Server automatisch 3 Nachrichten, die durch das RETRIEVE Kommando sofort nach dem Start des Servers abgerufen werden können.

echo "RETRIEVE" | nc localhost 7878
Test1
echo "RETRIEVE" | nc localhost 7878
Test2
echo "RETRIEVE" | nc localhost 7878
Test3

2.1.2 Verhalten des Servers bei Kommandos

  • STAGE: Der Server speichert die Nachricht
  • COMMAND: Der Server wertet das Kommando aus, speichert es aber nicht! Die Ausführung von Kommandos ist in dieser Aufgabe noch nicht zu implementieren.
  • RETRIEVE: Der Server gibt die älteste Nachricht zurück. Die Nachricht steht danach auf dem Server nicht mehr zur Verfügung.

2.1.4 Ausgaben des Servers auf der Konsole

Eventuell Auftretende Fehler gibt der Server auf der Konsole aus, ohne das Programm zu beenden.

Wird die Option -v angegeben, dann gibt der Server zusätzlichen Informationen aus (siehe obiges Kapitel dazu).

3.1 Fehlerbehandlung

Wie bereits mehrfach erwähnt, geschieht auch in Rust die Fehlerbehandlung wie mit Javas checked Exceptions, in dem spezielle Fehler und Ergebnisse in generische Fehler und Ereignisse umgeformt werden, um diese dann nach ‘oben’ durch zureichen. Auf der höchsten Ebene werden dann die Fehler behandelt. Bei Rust kommt noch dazu, dass man Results auch lokal in einer Funktion kombiniert, um dann alle Fehler innerhalb dieser Funktion (Top-level Handler) behandelt.

Als Basiswerkzeug haben Sie dazu bereits die Traits [std::convert::From][] und [std::convert::Into][] kennen gelernt. Es genügt eines davon zu implementieren.

Wenn man aber nicht einfach nur Fehler durchreichen möchte, sondern volle Results, muss man von Result zu dem entsprechenden Result der aufrufenden Funktion kommen. Dazu kann man zu ‘Result-Kombinatoren’ greifen. Die Funktion map wandelt den Ok-Typ in einen anderen um, map_err wandelt den Fehlertyp. Möchte man also beides, sieht der Aufruf folgendermaßen aus:

res.map(....).map_err(....)

Das ist derzeit noch ‘aufwendig’ als Syntax zu schreiben, entsprechende RFC’s um dies zu vereinfachen existieren bereits (vgl. Evolution der Fehlerbehandlung in Rust: match()->try!->?).

Ihre Lösung dieser Aufgabe hat somit idealerweise einen eigenen Fehlertypen, der wiederum den ‘ParseError’-Typen aus hw9:task1 als auch den/die in dieser Aufgabe auftretende Fehlertypen enthält.

4.1 Tipps

  • Zum Speichern eignet sich die VecDeque, mit der sich das oben genannte FIFO-Verhalten gut abbilden lässt.
  • Früher an später denken: gut Aufteilung von Aufgaben in Funktionen, Module und Bibliotheken macht die folgenden Aufgaben einfacher.
  • Zum Testen eignet sich netcat:
echo "STASH My privat hash: :) !" | nc 127.0.0.1 7878
echo "COMMAND Beam me up!" | nc 127.0.0.1 7878
echo "RETRIEVE" | nc 127.0.0.1 7878