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

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

240 5 Netzwerkprogrammierung in der Praxis<br />

9–10<br />

15–19<br />

21–26<br />

27–29<br />

31–34<br />

36–45<br />

<strong>mit</strong> Hilfe der getaddrinfo()-Funktion protokollunabhängig implementiert.<br />

tcp_listen() kann deshalb sowohl im IPv4- als auch im IPv6-Umfeld (<strong>und</strong><br />

da<strong>mit</strong> selbstverständlich auch in einem gemischten IPv4-/IPv6-Umfeld) eingesetzt<br />

werden.<br />

Die Funktion erwartet beim Aufruf drei Argumente: In nodename wird der IP-<br />

Name oder die IP-Adresse, an die der annehmende Socket geb<strong>und</strong>en werden<br />

soll, übergeben. Der IP-Name bzw. die IP-Adresse ist in der Regel nur auf<br />

Serversystemen <strong>mit</strong> mehreren IP-Adressen von Interesse. In diesem Fall kann<br />

über nodename gesteuert werden, auf welcher Adresse der Server eingehende<br />

Verbindungen annehmen soll. Hat das Serversystemen nur eine einzige IP-<br />

Adresse oder soll der Dienst auf allen IP-Adressen Verbindungen annehmen, so<br />

wird für nodename der Wert NULL übergeben. Der zweite Parameter servname<br />

transportiert den Servicenamen oder den Port, auf dem der Socket hören soll<br />

<strong>und</strong> über backlog wird die Länge der Listen-Queue beeinflußt. Die Funktion<br />

gibt bei Erfolg den Socketdeskriptor des neu erstellten annehmenden IPv4-<br />

oder IPv6-<strong>Sockets</strong> zurück. Im Fehlerfall liefert tcp_listen() den Wert -1.<br />

Als erstes initialisiert tcp_listen() eine Hints-Adreßstruktur, <strong>mit</strong> deren Hilfe<br />

der nachfolgende Aufruf von getaddrinfo() in die richtigen Bahnen gelenkt<br />

wird. Das AI_PASSIVE-Flag zeigt an, daß es sich bei dem neuen Socket um<br />

einen annehmenden Socket handeln soll. Über die beiden Flags AF_UNSPEC<br />

<strong>und</strong> SOCK_STREAM legen wir schließlich fest, daß wir <strong>mit</strong> den er<strong>mit</strong>telten Daten<br />

später einen TCP-Socket für wahlweise IPv4 oder IPv6 anlegen wollen.<br />

Die getaddrinfo()-Funktion liefert nun eine Liste von einer oder mehreren<br />

addrinfo-Strukturen zurück, deren Elemente direkt zum Aufbau einer<br />

Netzwerkverbi<strong>und</strong>ung eingesetzt werden können. Aus diesem Gr<strong>und</strong> iteriert<br />

tcp_listen() anschließend über diese Ergebnisliste <strong>und</strong> versucht, <strong>mit</strong> Hilfe<br />

der er<strong>mit</strong>telten Adreßinformationen einen passiven Socket zu öffnen.<br />

Hierzu wird als erstes ein neuer Socket erstellt. Für domain, type <strong>und</strong><br />

protocol (vgl. dazu Abschnitt 4.3.1) werden der socket()-Funktion die<br />

über getaddrinfo() er<strong>mit</strong>telten Werte übergeben. Falls der Aufruf der<br />

socket()-Funktion fehlschlägt, wird sofort der nächste Schleifendurchlauf begonnen<br />

<strong>und</strong> da<strong>mit</strong> die nächste addrinfo-Struktur aus der Ergebnisliste von<br />

getaddrinfo() probiert.<br />

Für den neuen Socket wird nun als erstes die Socketoption SO_REUSEADDR<br />

<strong>mit</strong>tels setsockopt() gesetzt. Dies erlaubt einen Neustart des Servers auch<br />

dann, wenn noch Kindprozesse der alten Serverinstanz aktiv sind oder sich<br />

noch Netzwerkverbindungen einer alten Instanz im Verbindungsabbau befinden<br />

(etwa im TCP-Zustand TIME_WAIT).<br />

Anschließend wird der Socket <strong>mit</strong> bind() an den spezifizierten Port geb<strong>und</strong>en<br />

<strong>und</strong> durch listen() in einen horchenden umgewandelt. Auch die Werte<br />

für die Parameter address <strong>und</strong> address_len der bind()-Funktion (vgl. dazu<br />

Abschnitt 4.3.4) werden einfach der aktuellen addrinfo-Struktur entnommen.

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

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!