05.11.2013 Aufrufe

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

268 5 Netzwerkprogrammierung in der Praxis<br />

21<br />

22 for(;;)<br />

23 {<br />

24 /* eintreffende Signale synchron annehmen */<br />

25 sigwait( &sigset , &signal );<br />

26 if( signal == SIGTERM )<br />

27 break;<br />

28 }<br />

29<br />

30 return;<br />

31 }<br />

5.3.2 Ein neuer Thread pro Client<br />

33–43<br />

45–47<br />

53–75<br />

Für jede Clientanfrage startet der nebenläufige Server einen neuen Thread,<br />

der sich dann um die Beantwortung der Anfrage kümmert. Die worker()-<br />

Funktion aus Beispiel 5.13 bildet die Startfunktion dieser dynamisch erzeugten<br />

<strong>Threads</strong> <strong>und</strong> erhält als einzigen Parameter den Socketdeskriptor für den<br />

aktuellen Client. Die Startfunktion fungiert lediglich als Mantelfunktion für<br />

handle_client(), übergibt also die Aufgabe sofort an handle_client() <strong>und</strong><br />

beendet abschließend die Verbindung zum Client. 7<br />

Nachdem sich der Hauptthread nach dem Dæmonstart ausschließlich um die<br />

Signalbehandlung kümmert, wird die Bearbeitung der eingehenden Clientverbindungen<br />

ebenfalls in einen eigenständigen Thread ausgelagert. Die Startfunktion<br />

dieses Accept-Handlers erhält vom Hauptthread als einziges Argument<br />

den Socketdeskriptor des zuvor geöffneten, horchenden <strong>Sockets</strong>.<br />

Der Accept-Handler verarbeitet dann in einer Endlosschleife die neuen Clientanfragen.<br />

Der Beginn der accept()-Schleife verläuft analog zum iterativen<br />

Server: Der Thread wartet <strong>mit</strong> accept() auf eingehende Verbindungen <strong>und</strong><br />

protokolliert eventuell auftretende Fehler an den Syslog-Dienst. 8 Anders als in<br />

Beispiel 5.9 kann die accept()-Funktion übrigens nicht von einem SIGTERM-<br />

Signal unterbrochen werden, weshalb wir an dieser Stelle auf die sonst übliche<br />

Sonderbehandlung verzichten können. Das Signal ist im Dæmonprozeß für alle<br />

<strong>Threads</strong> blockiert <strong>und</strong> wird vom Hauptthread in der sigcatcher()-Funktion<br />

explizit behandelt.<br />

7 Anstatt eine neue Startfunktion einzuführen, hätten wir selbstverständlich auch<br />

die handle_client()-Funktion als Startfunktion umgestalten können. Die neue<br />

Mantelfunktion worker() hilft uns jedoch dabei, die handle_client()-Funktion<br />

unverändert in allen Beispielprogrammen einsetzen zu können.<br />

8 Wie schon beim iterativen Server führt auch hier ein Fehler in accept() nicht<br />

zum Abbruch des Dæmons (vgl. dazu die Begründung aus Abschnitt 5.2.1).

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!