|
|
7 년 전 | |
|---|---|---|
| .. | ||
| README.md | 7 년 전 | |
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, indem Sie diese als
srv-commands Bibliothek in task2 benutzen, um die Kommandos an den
Server zu parsen. Kopieren Sie dazu Ihre Dateien aus task1 in das
srv-commands Verzeichnis.
Implementieren Sie den Webserver, in dem Sie TCPListener verwenden.
Sorgen Sie in dieser ersten Ausbaustufe dafür, dass der Server ‘Orders’ (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 immer nur eine Anfrage zu jeder Zeit beantwortet.
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
-v OptionMit der -v Ausgabe gibt der Server folgende Informationen aus:
text
...
Received Control: Beam me up!
...
Benötigen Sie darüber hinaus weitere Ausgaben, so geben Sie diese bitte nur bei -vv, -vvv usw. aus.
-a OptionMit der -a Option wird die Default Adresse: 127.0.0.1 überschrieben.
-p OptionMit der -p Option wird der Default Port: 7878 überschrieben.
test OptionWird diese Option mit angegeben, dann erstellt der Server automatisch 3 Orders, 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
-v Option gesetzt ist. Die Ausführung
von Kommandos ist in dieser Aufgabe noch nicht zu implementieren.Kommando RETRIEVE: Der Server gibt die älteste Order zurück. Die Order steht danach auf dem Server nicht mehr zur Verfügung. Sind keine Order vorhanden, so sendet der Server dem Client “No order on stage”
$ nc localhost 7878
RETRIEVE
No order on stage!
Eventuell auftretende Fehler gibt der Server auf der Konsole aus, ohne
das Programm zu beenden. So wird z.B bei einem unbekannten Kommando der
entsprechende Error Ihrer srv-commands Bibliothek ausgegeben, die
folgende Form haben könnte:
...
Error occurred: ParseError(UnknownCommand)
...
Wird die Option -v angegeben, dann gibt der Server zusätzliche Informationen aus (siehe obiges Kapitel dazu).
Ergänzen Sie Ihren Code mit entsprechenden Tests, um die Funktionalität in Ihren Libraries und Ihrem Server zu testen.
Wie bereits mehrfach erwähnt, geschieht auch in Rust die Fehlerbehandlung wie mit Javas checked Exceptions, indem spezielle Fehler und Ergebnisse in generische Fehler und Ereignisse umgeformt werden, um diese dann nach ‘oben’ durch zu reichen. 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) zu behandeln.
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.
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
Eine Kurzinfo zu netcat finden Sie in den tldr Seiten zu allen
Unix Kommandos . Dür ausführlichere Informationen benutzen Sie die man
page in Ihrem Container.