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.

188 4 Gr<strong>und</strong>lagen der Socket-Programmierung<br />

49–55<br />

57–59<br />

61–63<br />

übergebenen Socket eine TCP-Verbindung zur Gegenseite auf. Die Gegenstelle<br />

wird in der per Referenz übergebenen Socket-Adreßstruktur sa spezifiziert.<br />

Im Fehlerfall liefert die Funktion den Rückgabewert -1 <strong>und</strong> unser Programm<br />

beendet sich <strong>mit</strong> einem entsprechenden Hinweis.<br />

Anschließend können wir Daten über den Socket empfangen. Der Timeserver<br />

ignoriert alle Daten, die vom Client zum Server übertragen werden (weswegen<br />

wir das erst gar nicht probieren), schickt eine 32 Bit lange Ganzzahl <strong>mit</strong> den<br />

Sek<strong>und</strong>en seit dem 1. 1. 1900 um 0.00 Uhr an den Client <strong>und</strong> schließt danach<br />

umgehend die Verbindung. Unser Time-Client liest genau diesen Wert <strong>mit</strong><br />

der read()-Funktion vom Socket. Genaugenommen sollten wir abschließend<br />

prüfen, ob wir tatsächlich die geforderte Anzahl von Bytes, hier im Umfang<br />

einer 32 Bit langen Ganzzahl, vom Socket gelesen haben. Wir verzichten in<br />

diesem einfachen Beispiel jedoch aus Gründen der Übersichtlichkeit darauf.<br />

Vor der Ausgabe der aktuellen Uhrzeit müssen wir die erhaltene Zahl konvertieren:<br />

Zum einen wurde die 32-Bit Ganzzahl in Netzwerkdarstellung übertragen,<br />

sie muß daher in die Host Byte Order zurück übersetzt werden. Zum<br />

anderen verwenden sämtliche Zeitfunktionen der C-Bibliothek anstatt dem<br />

1. 1. 1900 den 1. 1. 1970 als Basis. Vom empfangenen Wert müssen also noch<br />

die Sek<strong>und</strong>en zwischen 1900 <strong>und</strong> 1970, das sind 2 208 988 800 Sek<strong>und</strong>en, subtrahiert<br />

werden, um die Anzahl der Sek<strong>und</strong>en seit dem 1. 1. 1970, 0.00 Uhr,<br />

zu er<strong>mit</strong>teln. Danach geben wir die Zeit auf der Standardausgabe aus.<br />

Zum Schluß schließen wir den Socket <strong>und</strong> beenden das Programm <strong>mit</strong> einer<br />

Erfolgsmeldung als Rückgabewert.<br />

Wir können nun das Time-Programm aus Beispiel 4.5 ausprobieren <strong>und</strong><br />

<strong>mit</strong> dem Aufruf von telnet aus Abschnitt 4.1.1 vergleichen. Abgesehen von<br />

den flankierenden Ausgaben, die das telnet-Kommando zusätzlich erzeugt,<br />

verhält sich der selbst geschriebene Time-Client wie erwartet:<br />

$ ./timeclient 192.168.1.1<br />

Mon May 17 17:22:38 2005<br />

Das Programm verbindet sich erfolgreich zum angegebenen Timeserver, öffnet<br />

also eine Verbindung zu Port Nummer 37 auf dem Rechner <strong>mit</strong> der IPv4-<br />

Adresse 192.168.1.1, <strong>und</strong> liefert das aktuelle Datum samt Uhrzeit.<br />

Aber auch verschiedene Fehler, die beim Aufruf von connect() auftreten<br />

können, lassen sich <strong>mit</strong> diesem Clientprogramm bereits veranschaulichen. Als<br />

erstes versuchen wir, eine Verbindung zu einem Rechnersystem herzustellen,<br />

auf dem der Time-Service nicht aktiviert ist:<br />

$ ./timeclient 192.168.1.2<br />

connect() failed: Connection refused<br />

In diesem Fall kommt selbstverständlich gar keine Netzwerkverbindung <strong>mit</strong><br />

Port 37 auf dem spezifizierten Zielsystem zustande. Der connect()-Aufruf

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

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!