Unix1 im Wintersemester 1994/95
6. Übungsblatt
Dieses Übungsblatt enthält ähnlich wie
das erste eine Sammlung von praktischen Aufgaben,
die nicht alle bearbeitet werden müssen.
Ihr könnt Euch eine der gestellten Aufgaben zur Bearbeitung
aussuchen.
Beachtet bitte, daß für
die einzelnen Aufgaben je nach Schwierigkeitsgrad und
Umfang unterschiedliche Maximalpunktzahlen zu erreichen sind.
Richtet Eure Wahl also nicht nur nach persönlichem Interesse,
sondern auch nach Eurem aktuellen Punktestand.
Die Noten für die Übungen ergeben sich wie folgt
aus der Gesamtpunktzahl der Übungsblätter:
- 150-136 = 1,
- 135-121 = 2,
- 120-106 = 3,
- 105-90 = 4,
- unter 90 = nicht bestanden.
Die Aufgaben enthalten neben der Grundaufgabenstellung noch Zusätze,
die weitere Funktionalitäten realisieren sollen und zusätzlich
Punkte bringen.
Aufgabe 1 (20 Punkte)
BuiltinKommando als Client ähnlich rwho(1).
Erweitert Euren msh um das builtinKommando mrwho.
Die Ausführung dieses Kommandos soll in dem Modul socket.c mit
Hilfe von Streamsockets in der InternetDomain bei dem Serverprozeß
unix1daemon beantragt werden.
Dieser Serverprozeß wird auf dem Rechner kraftbus.cs.tu-berlin.de
ausgeführt und ist über die Portnummer 4711
erreichbar.
Sollte der Daemon nicht installiert sein (der Aufruf von connect() scheitert),
könnt Ihr Euch an einen Tutor wenden.
mrwho soll
als builtinKommando ähnlich dem rwhoKommando im
CShell implementiert werden.
Nach Anfrage beim Server erhält der Client (also socket.c)
0 bis n Strings der Länge 18 Zeichen zurück.
Diese haben das Format username:hostname
,
wobei username und hostname jeweils bis zu 8 Buchstaben lang sein
können.
Da mrwho nur die Benutzer und Hostnamen der Unix1Bereiche
zurückliefern soll, müßt Ihr Euch beim Starten Eures
msh durch Anfrage beim Server in die entsprechende Datei
eintragen lassen und beim Verlassen des msh das Löschen
aus dieser Datei beantragen.
Diese Anfragen sollen durch die Funktionen void do_login()
und void do_logoff()
in socket.c realisiert werden.
Die beiden Funktionen sollen aus main.c aufgerufen werden.
Bei einer Anfrage zum Schreiben oder Löschen liefert der Server
die Zeichenkette "ok"
zurück,
wenn die Funktion richtig ausgeführt
werden konnte, ansonsten eine (maximal 18 Byte lange)
Fehlermeldung.
Die Protokollschnittstelle zum Server sieht vor,
daß in einer 18ByteNachricht eine Anforderung
übermittelt wird.
In einer Antwortnachricht, die ebenfalls immer 18 Byte lang ist,
werden die möglichen Rückgabewerte beschrieben.
In dem Puffer, der dem Server mit write() übergeben wird, müssen
für die Ausführung der einzelnen Funktionen zuerst folgende
ASCIIZeichen übergeben werden:
- für das Eintragen von Benutzer und Hostnamen,
- für die Anfrage (mrwho) und
- für das Löschen von Benutzer und Hostnamen.
Zusatzaufgaben zu Aufgabe 1:
(Hierzu ist jeweils eine kurze Dokumentation der in Aufgabe 2
verlangten Art zu schreiben.)
-
Aufgabe 1a (15 Punkte): Passender Server
-
Schreibt einen Server, der genau die Aufgaben wahrnimmt,
die unser für die Aufgabe vorgegebener Server erfüllt.
Er soll für jede
Clientanfrage einen neuen Prozeß starten, der die Anfrage dann
bearbeitet und das Format des übergebenen Strings auf Korrektheit
prüfen.
Die Bearbeitung dieses Teils ist Voraussetzung für 1b
und 1c.
-
Aufgabe 1b (10 Punkte)
Semantische Überprüfung der Parameter
-
Der übergebene String ist auch auf inhaltliche Korrektheit zu
prüfen.
Es muß also kontrolliert werden, ob sowohl der
angegebene Benutzer als auch der Rechner überhaupt existieren und
gegebenenfalls eine Fehlermeldung an den
Client gesandt werden.
-
Aufgabe 1c (5 Punkte) Nebenläufigkeitskontrolle
-
Zur Vermeidung nebenläufiger schreibender Zugriffe auf die
Benutzerliste durch mehrere Kindprozesse des Servers ist die Liste
bei Schreiboperationen durch den flock()Mechanismus
zu schützen.
Aufgabe 2 (30 Punkte)
Einfache ClientServerDatenbankanwendung
Implementiert eine einfache Datenbank als ClientServerAnwendung.
Der Server soll dabei als UnixDaemon implementiert sein,
die eigentliche
Datenbankdatei verwalten und Anfragen (lesend oder schreibend) von
einer ebenfalls zu implementierenden Clientanwe ndung beantworten bzw.
bearbeiten.
Der Inhalt der Datenbank ist Euch
überlassen; ein Datensatz soll aber mindestens aus drei Feldern
bestehen, wie z.B. bei einer Adressenkartei.
Der Server soll dem Client
die Operationen Einfügen, Löschen, Lesen und
SortierteAusgabe zur Verfügung stellen.
Zur sortieren Ausgabe
aller Datensätze dient ein durch den Server festgelegtes
Schlüsselfeld, z.B. der Nachname bei der Adressenkartei.
Für die Löschoperation muß
der Client einen kompletten Datensatz übergeben, den der Server
nur bei exakter Übereinstimmung löscht. Beim Lesen nur eines
Datensatzes muß der Client den Inhalt des Schlüsselfeldes
übergeben.
Falls mehrere gleiche Schlüsselfelder
existieren, liefert der Server trotzdem nur den ersten gefundenen
Datensatz zurück.
Client und Server kommunizieren
über Stream oder DatagrammSockets miteinander.
Der Server
startet bei jeder Anfrage durch einen Client einen neuen Prozeß,
der die Anfrage bearbeitet.
Potentiell können mehrere Clients
gleichzeitig auf den Server zugreifen; dieser Fall ist auch zu
testen.
Die dabei auftretenden Nebenläufigkeitsprobleme werden in einer
Zusatzaufgabe behandelt.
Eure Aufgabe ist neben der
Implementierung von Client und Server die Entwicklung eines einfachen
geeigneten Protokolls zwischen beiden und das Schreiben einer kurzen
Dokumentation mit Bedienungsanleitung für Euer Produkt.
In der
Dokumentation sollt Ihr den Aufbau Eurer Applikation beschreiben, Eure
Designentscheidungen begründen und auf Probleme bei der
Implementierung eingehen.
Der Dokumentationsteil geht zu einem Drittel
in die Gesamtbewertung ein.
Zusatzaufgaben zu Aufgabe 2:
(ebenfalls jeweils zu dokumentieren)
-
Aufgabe 2a (5 Punkte) Nebenläufigkeitskontrolle
-
Implementiert eine simple Nebenläufigkeitskontrolle für den
Server mit Hilfe der flock()Funktionen.
Dabei soll bei einem schreibenden Zugriff die gesamte
Datenbankdatei für
weitere Schreibzugriffe gelockt werden, damit durch den möglichen
gleichzeitigen Zugriff anderer Kindprozesse des Servers keine
Nebenläufigkeitsprobleme entstehen.
(lockf() darf alternativ verwendet werden.)
-
Aufgabe 2b (10 Punkte)
Zugriffsschutz und kontrolle
-
Der Client soll bei jeder Anfrage an den Server die
UID des Benutzers mit übergeben.
Der Server prüft dann an Hand einer kleinen Datenbasis,
auf die nur derjenige Zugriff hat, dem der Server ,,gehört'',
ob der Benutzer überhaupt zugriffsberechtigt ist.
Dabei soll zwischen lesendem und schreibendem Zugriff
unterschieden werden können.
Beispielsweise können in einer Datei die Benutzernamen
aller Leute stehen, die lesenden und schreibenden Zugriff haben,
in einer anderen die Logins derer, die nur lesen dürfen.
Wer in beiden Dateien nicht vorkommt, darf auch nicht zugreifen.
Für die Überprüfung
von Lesezugriffen ist ein Mechanismus vorzusehen,
der dem Server mitteilt, daß
allen Benutzern der Zugriff gestattet ist
(z.B. ein spezieller Login).
Bei einem als illegal erkannten Zugriff ist dem Benutzer
dies durch eine Fehlermeldung anzuzeigen.
-
Aufgabe 2c (5 Punkte)
Protokollierung von Zugriffen
-
Der Server soll alle schreibenden und illegalen Zugriffe
in einer weiteren Datei im Klartext mitprotokollieren.
Zu einem Protokolleintrag gehören
der Name des zugreifenden Benutzers, Uhrzeit und Datum,
die Art des Zugriffs, gegebenenfalls die beim Zugriff
übergebenen Parameter (also der Datensatz)
und bei einer illegalen Operation der Grund der Ablehnung.
Ist der Zugriffsschutz aus 2b nicht implementiert,
sind nur die Schreibzugriffe festzuhalten.
-
Aufgabe 2d (5 Punkte)
Suchfunktionen
-
Der Server soll zusätzlich zu den bereits vorhandenen die
Funktion Suchen anbieten.
Der Client übergibt hierfür einen Suchstring
(ohne Wildcards).
Der Server durchsucht alle Felder seiner Datensätze
nach diesem String und übergibt
dem Client alle Datensätze,
bei denen ein Match aufgetreten ist.
Darunter fallen auch Matches auf Teilstrings,
d.h. der Suchstring muß kein vollständiges Datenfeld enthalten.
-
Aufgabe 2e (5 Punkte)
Wechsel des Schlüsselfeldes
-
Die Parameter der Operationen Lesen und SortierteAusgabe
sollen so erweitert werden, daß für die jeweilige
Operation ein anderes als das Standardfeld als Schlüsselfeld
angegeben werden kann.
Aufgabe 3 (50 Punkte)
Rechnen mit großen Zahlen als
ClientServerAnwendung
Entwickelt einen Server, der Clients Operationen auf große
Integers mit bis zu mehreren hundert
Stellen zur Verfügung stellt.
Der Client soll über ein geeignetes Protokoll auf
Basis von BSDSockets die Parameter und die gewünschte Operation
spezifizieren können.
Der Server gibt ihm danach das Ergebnis zurück.
Als Operationen sollen mindestens
Addition, Subtraktion, Multiplikation, Division, Vorzeichenwechsel, Potenzierung
und die elementaren Vergleichsoperationen
(gleich, ungleich, größer, kleiner,
größergleich, kleinergleich) vorhanden sein.
Es dürfte praktisch sein, alle Zahlen im Client und im Protokoll
als Strings zu repräsentieren, damit das für die
Rechenoperationen benötigte und unter Umständen komplizierte
Zahlenformat ganz im Server verborgen bleibt.
Neben dem Server ist ein Client zu entwickeln,
der die angebotenen Operationen sinnvoll testet.
Außerdem ist eine Dokumentation zu erstellen,
die den Aufbau Eurer Applikation, das gewählte
Zahlenformat und die bei den Rechenoperationen verwendeten
Algorithmen beschreibt.
Sie geht etwa zu 25% in die Gesamtbewertung ein.
Zusatzaufgaben zu Aufgabe 3:
(ebenfalls zu dokumentieren)
-
Aufgabe 3a (5 Punkte) Operation GGT
-
Der Server soll zusätzlich die Operation GGT
(größter gemeinsamer Teiler) anbieten.
-
Aufgabe 3b (5 Punkte) Primzahltest
-
Der Server soll prüfen können,
ob eine durch den Client übergebene Zahl eine Primzahl
ist und einen Booleschen Wert als Ergebnis liefern.
Es sind auch probalistische Tests mit ausreichend hoher
Wahrscheinlichkeit erlaubt.
-
Aufgabe 3c (10 Punkte) Primfaktorzerlegung
-
Der Server soll eine übergebene Zahl in ihre
Primfaktoren zerlegen können.
Dem Client wird die Liste der Faktoren nach abgeschlossener
Faktorisierung komplett zurückgeliefert.
Für viele Algorithmen ist es übrigens praktisch,
vorher 3a und 3b zu implementieren.
-
Aufgabe 3d (10 Punkte) Paralleler Client
-
Implementiert einen Client,
der nebenläufig Operationen
an mehrere auf verschiedenen Rechnern laufende Server verteilt,
nichtblockierend (per select()) auf die Ergebnisse wartet,
diese wiederum für neue Operationen nutzt, usw.
Der Client soll also seinen internen Ablauf durch
Aufgabenverteilung über mehrere Server seinen
internen Ablauf weitgehend parallelisieren.
Überlegt Euch eine Anwendung für die dies
sinnvoll erscheint (z.B. wieder eine Primfaktorzerlegung).
(Das liegt natürlich weit über dem Unix1Niveau,
aber vielleicht mag es ja jemand just for fun ausprobieren.)