Zurück zum Inhaltsverzeichnis des Manuskripts verteilte Systeme

2.2 Sockets

2.2.1 Kommunikation über Sockets

IP-Adressen und Ports

Ein Socket ist der Endpunkt eines Datentransportsystems in einer Anwendung, das Daten zu einer anderen Anwendung auf einem anderen Rechner befördert. Das heißt, dass bei der Benutzung eines Sockets sowohl ein anderer Rechner als auch eine Anwendung auf diesem Rechner adressiert werden müssen. Die Kapitel 5 (Vermittlungsprotokolle im Internet) und 4 (Transportprotokolle im Internet) befassen sich ausführlich mit diesen Adressierungen. Hier genügt es festzuhalten, dass sowohl Rechner im Internet als auch Anwendungen auf Rechnern jeweils durch Zahlen in einer bestimmten Schreibweise adressiert werden. Bei dem Internetprotokoll IP in der weit verbreiteten Version 4 haben Rechneradressen eine Form wie die folgende:

141.64.226.55

Sie heißen IP-Adressen. Eine Anwendung auf einem bestimmten Host wird dagegen durch eine strukturlose natürliche Zahl zwischen 1 und 65535 angesprochen, die Portnummer oder kurz Port genannt wird. Da IP-Adressen für menschliche Benutzer etwas mühsam zu handhaben sind, gibt es für sie eine alternative Schreibweise, die Domänenname genannt wird. Der Domänenname zu der oben angegebenen IP-Adresse lautet

www.bht-berlin.de

und ist deutlich leichter zu handhaben als die zugehörige Zahl. Um IP-Adressen und Domänennamen aufeinander abzubilden ist ein eigener Internetdienst eingerichtet worden. Er heißt Domain Name System (DNS) und ist Thema des Abschnitts 3.3 (Domain Name System).

Hinweis zur Programmierung

Bei der Programmierung in einer vernetzten Umgebung, so wie das bei den Übungen zur Lehrveranstaltung der Fall ist, werden üblicherweise zum Schutz der Rechnersysteme Firewalls eingesetzt. Mit ihnen können unter anderem IP-Adressen und Portnummern blockiert werden. Man vergleiche dazu den Abschnitt 6.3 (Firewalls) dieses Manuskripts. Es ist in solchen Umgebungen notwendig, mit der zugehörigen Systemverwaltung eine Absprache über das zumindest zeitweise Freigeben von IP-Adressen und Portnummern zu treffen.

In dem zur Lehrveranstaltung gehörenden Übungsraum sind alle Rechner über ihre IP-Adresse ansprechbar, und für den Zeitraum der Übungen sind die Portnummern von 9860 bis 9880 (einschließlich) freigegeben. Dass selbst eine solche Festlegung zu praktischen Problemen beim Programmieren führen kann, zeigt die dritte Übungsaufgabe, bei der ein Werkzeug zu benutzen ist, das durch seine Voreinstellung auf wechselnde Weise Portnummern außerhalb des freigegebenen Bereichs verwendet. Wie in den Übungsprogrammen damit umgegangen werden kann, wird im Abschnitt 6.3 beschrieben.

Socketinformation

Wenn zwei Anwendungen im Internet miteinander kommunizieren wollen, dann richten sie zunächst beide einen Socket ein. Dabei müssen sie entscheiden, ob sie einen Stream Socket oder einen Datagram Socket verwenden wollen. Und sie müssen beachten, dass es keine gemischten Verbindungen gibt: Beide müssen das gleiche Transportprotokoll verwenden. Haben sie sich für einen Stream Socket entschieden, dann nennt man die dadurch entstehende Verbindung der beiden Sockets verbindungsorientiert, anderenfalls, also beim Einsatz von Datagram Sockets, verbindungslos.

Zu jedem der beiden Sockets gehören fünf Angaben, die als Socketinformation bezeichnet werden und deren erste Angabe das verwendete Transportprotokoll ist. Wenn man von den anderen vier Angaben absieht, entsteht beispielsweise für die beiden Sockets folgende Socketinformation:

Socketinformation des Sockets in der Anwendung1: Protocol : TCP Socketinformation des Sockets in der Anwendung2: Protocol : TCP

Zwei weitere Angaben der Socketinformation sind die IP-Adresse des jeweils lokalen Rechners und die Portnummer der jeweiligen Anwendung auf diesem Host. Wenn in Fortführung des Beispiels die Anwendung1 auf dem Rechner mit der IP-Adresse 162.79.102.6 arbeitet und dort die Portnummer 9056 belegt und sich die Anwendung2 auf dem Rechner mit der IP-Adresse 141.64.89.65 mit der Portnummer 1088 befindet, dann sieht die Socketinformation zu den beiden Sockets folgendermaßen aus:

Socketinformation des Sockets in der Anwendung1: Protocol : TCP Local Host : 162.79.102.6 Local Port : 9056 Socketinformation des Sockets in der Anwendung2: Protocol : TCP Local Host : 141.64.89.65 Local Port : 1088

Jede der beiden Anwendungen will der jeweils anderen Daten senden. Dazu müssen beide ihr Ziel adressieren können. Das heißt, sie müssen wissen, welcher Rechner (Remote Host) und welche Anwendung auf diesem Rechner (Remote Port) anzusprechen ist. Die vollständige Socketinformation des Beispiels sieht damit folgendermaßen aus:

Socketinformation des Sockets in der Anwendung1: Protocol : TCP Local Host : 162.79.102.6 Local Port : 9056 Remote Host : 141.64.89.65 Remote Port : 1088 Socketinformation des Sockets in der Anwendung2: Protocol : TCP Local Host : 141.64.89.65 Local Port : 1088 Remote Host : 162.79.102.6 Remote Port : 9056

Was für die eine Anwendung lokal ist, ist für die andere fern (remote) und umgekehrt. Wie bei einem Aufbau einer Socketverbindung diese Angaben auf beiden Seiten der Verbindung zusammengetragen werden, wird in den nächsten Abschnitten erläutert und durch Beispiele untermauert. Für den physikalischen Transport der Daten durch die Socketverbindung werden letztlich die physikalischen Adressen (MAC-Adressen) der beiden beteiligten Hosts benötigt. Diese Adressen werden erst auf der Netzzugangsschicht (Schicht 1 im DoD-Modell) bzw. der Sicherungsschicht (Data Link Layer, Schicht 2 des ISO/OSI-Modells) eingebunden. In der Transportschicht spielen sie keine Rolle.

Kommunikationsmodelle

Die Anwendungsprogrammierung mit Sockets wird durch das jeweils zu Grunde liegende Kommunikationsmodell geprägt, das bei den beiden Socketarten unterschiedlich ist:

Funktionalität der Stream Sockets

Sollen zwei Anwendungen mit Hilfe von Stream Sockets miteinander kommunizieren, dann muss eine der beiden als Server angelegt werden, die andere als Client. Die Anwendung, die den Server realisiert, wird meist selbst als Server bezeichnet. Sie richtet zunächst einen sogenannten Serversocket ein. Ein Versuch, aus diesem Socket zu lesen, würde zu einem Fehler führen, bei Java würde eine entsprechende Exception geworfen werden. Mit einem accept()-Aufruf wartet der Server an diesem Socket darauf, dass sich ein Client mit ihm verbindet.

Die Anwendung, die den Client realisiert, meistens selbst Client genannt, richtet einen Clientsocket ein, der durch eine Röhre veranschaulicht werden kann, die in der Anwendung beginnt und vorläufig noch ein freies Ende hat. Mit einem connect()-Aufruf verbindet der Client seinen Socket mit dem des Servers, der dadurch aus seinem Warten im accept()-Aufruf befreit wird. In der Java-Programmierung können connect()-Aufrufe Teil eines bestimmten Konstruktors sein und dadurch vom Programmierer indirekt aufgerufen werden.

Erreicht den Server, der in einem accept()-Aufruf wartet, der Verbindungswunsch eines Clients, dann verdoppelt er seinen Serversocket und wandelt das Duplikat in einen Clientsocket um. Auch dieser Clientsocket kann durch eine Röhre veranschaulicht werden, die in der Clientanwendung beginnt und an der anderen Seite offen ist. Die beiden Clientsockets, anschaulich die beiden Röhren, werden miteinander verbunden, wodurch eine zusammenhängende Röhre zwischen dem Client und dem Server entsteht. Für jede der beiden Anwendungen ist das jeweilige lokale Ende dieser Röhre ihr Socket, über den sie mit der Partneranwendung kommuniziert.

Duplexbetrieb

Im Gegensatz zu den, bereits im Abschnitt 1.4.2 (Kommunikationstechniken) vorgestellten lokalen Pipelines sind Verbindungen über Stream Sockets bidirektional. In ihnen können gleichzeitig und unabhängig voneinander Daten in beiden Richtungen übertragen werden. Stream Sockets erlauben einen (Voll-)Duplexbetrieb.

Parallele und iterative Server

Im Server steht nach der Verdopplung des Serversockets dieser sofort wieder für Verbindungswünsche weiterer Clients zur Verfügung. Der Server kann einen Thread erzeugen, dem er das Serversocketduplikat übergibt, und der die Kommunikation mit dem Client übernimmt, während er selbst an dem Serversocket auf Anforderungen durch weitere Clients wartet. Einen solchen Server nennt man einen parallelen Server. Ein Server heißt iterativ, wenn er die Kommunikation mit dem Client nicht an einen neuen Thread delegiert, sondern selbst übernimmt und erst danach auf die nächste Client-Anforderung wartet. Die zweite Übungsaufgabe sieht beispielsweise vor, dass es jeweils nur immer genau einen Client gibt. Dieser stellt seine Anforderung an den Server und wartet dann auf das Ergebnis. Das heißt, dass es für diese Übungsaufgabe ausreicht, einen iterativen Server zu realisieren.

Datagram Sockets

Haben sich die beiden Anwendungen, die miteinander kommunizieren wollen, für Datagram Sockets entschieden, dann entsteht eine Peer-to-Peer-Kommunikation. Beide Partner sind gleichberechtigt, und jeder von ihnen richtet einen Datagram Socket ein. Anschaulich ist das ein Haus-Briefkasten mit einem direkten Zugang zu einem Postdienst. Der Benutzer wirft einen adressierten Brief ein und der Postdienst befördert ihn. Auf der anderen Seite legt der Postdienst einen ankommenden Brief in den Haus-Briefkasten, von wo er vom Adressaten entnommen werden kann. Genau wie bei den Postdiensten Briefe auf dem Transport verloren gehen oder in der Reihenfolge verändert werden können, kann dies auch Datagrammen geschehen. Es kann sogar vorkommen, dass ein Datagramm einem Empfänger mehrfach zugestellt wird.

Anwendungen, die von ihrer Programmierung her einem Peer-To-Peer-Modell folgen, können so organisiert werden, dass eine von ihnen Ressourcen zur Verfügung stellt, während die andere Ressourcen anfordert, wodurch auf dieser Anwendungsebene eine Client/Server-Kommunikation entsteht. Das Domain Name System (DNS) geht diesen Weg und ist ein typisches Anwendungsbeispiel für einen Datagrammdienst. Dort werden zwischen DNS-Client und DNS-Server Daten der folgenden Art ausgetauscht:

Client an Server: Host: www.bht-berlin.de IP : ? Server an Client: Host: www.bht-berlin.de IP : 141.64.226.55


Zurück zum Inhaltsverzeichnis des Manuskripts verteilte Systeme