Universität Ulm -Sektion Angewandte Informationsverarbeitung
5.Übungsblatt (01.06.99 bis 15.06.99)
zur Vorlesung Systemnahe Software II (SS 99)
Aufgabe 1 (20 Punkte)
In diesem Übungsblatt soll eine Client-Server-Applikation mit Hilfe von
name pipes (FIFOs - siehe man
mknod) zwischen nicht-verwandten Prozessen implementiert werden. Der Server ist
ein einfacher Dateiserver ähnlich wie im Skript: Er erhält einen
Dateienamen vom Client und liefert den Inhalt der Datei an
den Client zurück. Er soll in der Lage sein, mehrere Clients (nacheinander)
zu bedienen. Der Server besitzt eine "öffentlich" bekannte FIFO,
über die die Anfragen der Clients (sog. Requests) hereinkommen. Jeder
Client erhält dann einen eigenen "Kommunikationskanal" vom Server, auf dem ihm die Datei zugesandt wird.
Jeder Client stellt zuerst eine Verbindung zum Server her und erzeugt dann eine eigene FIFO mit einem im
System eindeutigen Namen (z.B. via getpid()). Dieser wird in der Anfrage des Clients an den Server
mitübergeben. Der Server kann somit die Antwort der Anfrage in die client-spezifische FIFO schreiben.
Falls die angeforderte Datei nicht existiert oder nicht zum Lesen geöffnet werden kann, erhält der Client
eine entsprechende Fehlermeldung anstatt der Datei
Achtung:
-
Die Clients schreiben evtl. gleichzeitig in die vom Server bereitgestellte FIFO. Damit sich die Anfragen
der Clients dabei nicht vermischen, muß sichergestellt werden, daß Anfragen atomar sind und die
Puffergröße der FIFO nicht überschreiten.
- Öffnet der Server seine FIFO nur zum Lesen, so erhält er jedesmal wenn die Anzahl der Clients auf Null
zurückgeht EOF. Um diesen für den Server unangenehmen Fall zu verhindern, behilft man sich mit dem
folgenden Trick: der Server öffnet die FIFO erst zum Lesen und dann auch zum Schreiben (auch wenn
er das gar nicht braucht). Vorsicht: O_RDWR ist bei FIFOs als Flag bei open() nicht möglich - deshalb
muß open()hier zweimal getrennt aufgerufen werden. Außerdem: open() blockiert. Somit muß hier
unbedingt vor dem Öffnen O_NONBLOCK (siehe Übungen) angegeben werden. Dann sollte der Server
aber wieder für das Lesen auf Blocking zurückschalten J (einfach, nicht?) z.B. via fcntl().
- Tritt im Server oder Client ein Fehler auf, so wird sicherlich in mindestens einem Prozeß ein System-
aufruf auf ewig (oder noch länger) blockiert. Lösen Sie das Problem (optional!) über Timeouts (man
alarm).
- Schauen Sie sich doch einfach die Beispiele aus den Übungen an.