Socket
aus Wikipedia, der freien Enzyklopädie
Dieser Artikel oder Abschnitt bedarf einer Überarbeitung. Näheres ist auf der Diskussionsseite angegeben. Hilf bitte mit, ihn zu verbessern, und entferne anschließend diese Markierung. |
Ein Socket (englisch wörtlich übersetzt „Sockel“ oder „Steckverbindung“) ist eine bidirektionale Software-Schnittstelle zur Interprozess- (IPC) oder Netzwerk-Kommunikation. Sockets sind vollduplexfähige Alternativen zu Pipes oder Shared Memory.
Sockets bilden eine plattformunabhängige, standardisierte Schnittstelle (API) zwischen der Netzwerkprotokoll-Implementierung des Betriebssystems und der eigentlichen Anwendungssoftware.
Inhaltsverzeichnis |
[Bearbeiten] Arten von Sockets
Die Berkeley Software Distribution (BSD) verwendet Netzwerk-Sockets seit 1983 in Form der Berkeley Sockets API. Auch Linux oder Solaris verwenden BSD-Sockets. Der Zugriff erfolgt ähnlich wie auf Dateien. Windows verwendet eine den Berkeley Sockets nachempfundene API, die Windows Sockets (Winsock).
Unix verwendet Sockets auch zur lokalen Interprozess-Kommunikation, sogenannte Unix Domain Sockets. Sie sind Teil des POSIX-Standards. Hierbei wird auf Sockets und auf Dateien in gleicher Art und Weise zugegriffen.
[Bearbeiten] Geschichte
Der Kommunikationsablauf heutiger Netzwerkapplikationen, beispielsweise von Client-Server-Anwendungen folgt einem einfachen Konzept:
- Verbindungsaufbau
- Datenaustausch
- Verbindungsabbau
Um die für diesen Ablauf nötige Funktionalität dem Programmierer zur Verfügung zu stellen, wurden im Laufe der Zeit einige Schnittstellen (= Interfaces) entwickelt, von denen das Sockets-Interface wohl das erfolgreichste ist. Ihren Ursprung hat diese Schnittstelle im traditionellen „Everything-is-a-file“-Konzept von Unix. Die Eingabe/Ausgabe-Behandlung (I/O) unter Unix folgt dem sogenannten Open-Read-Write-Close-Algorithmus. „Open“ (= Öffne) überprüft die Berechtigung bzw. gewährleistet den Zugriff auf I/O-Ressourcen. Darauf folgen eine oder mehrere Read/Write (=Lies/Schreibe)-Zyklen, wobei „Read“ Daten von der I/O-Ressource liest und dem Benutzer zur Verfügung stellt, „Write“ hingegen Daten schreibt (z. B. Speichervorgang). Zum Abschluss des Vorgangs erfolgt das Kommando „Close“. Als Netzwerksupport in Unix-Systemen integriert wurde, wollte man die Kommunikation ähnlich diesem ORWC-Algorithmus gestalten. Aus diesen Bemühungen entstand unter BSD-Unix die Sockets-Schnittstelle.
Sockets wurden ursprünglich nur für das BSD-Unix-Betriebssystem entwickelt, definieren jedoch mittlerweile einen De-facto-Standard. So modellierte auch Microsoft das Windows Socket Interface der Windows-Betriebssysteme auf Basis der Berkeley-Sockets.
[Bearbeiten] Allgemeines
Bei einem Socket handelt es sich um ein Ende einer Kommunikationsschnittstelle zwischen zwei Programmen, welche Daten über ein Netzwerk austauschen. Eine Applikation fordert einen Socket vom Betriebssystem an und kann über diesen anschließend Daten verschicken und empfangen. Das Betriebssystem hat die Aufgabe, alle benutzten Sockets sowie die zugehörigen Verbindungsinformationen zu verwalten. Verschiedene Socket-Klassen repräsentieren die Verbindung auf der Client- wie auf der Serverseite. Eine Socket-Adresse kann zum Beispiel definiert sein durch:
- Identifikationsnummer des Local-Host/seiner 32-Bit-IP-Adresse
- Portnummer des Local-Host/16 Bit
sin_family
, das heißt der zugehörigen Adressfamilie des Netzwerks (z. B. AF_INET = Adressfamilie Internetadresse)
Diese Informationen sind allerdings vom verwendeten Protokoll abhängig, so ist die Adress-Information für einen Unix Domain Socket (wird benutzt für Interprozesskommunikation) ein Dateipfad. Typischerweise handelt es sich bei der Adress-Information im Internet um die IP-Adresse und den Port.
Die Vergabe der Port-Nummern erfolgt beim Verbindungsaufbau. Die Port-Nummern werden großteils vom System beliebig vergeben. Ausnahmen sind die so genannten Well-Known-Ports welche von bekannten Applikationen fix verwendet werden.
[Bearbeiten] Stream Sockets und Datagram Sockets
Der wesentliche Unterschied zwischen diesen beiden Typen besteht darin, dass Stream Sockets über einen kontinuierlichen Zeichen-Datenstrom kommunizieren, wohingegen Datagram Sockets auf dem Senden von einzelnen Nachrichten basieren.
Stream Sockets verwenden meist TCP, was aufgrund der Eigenschaften von TCP zu einer hohen Verlässlichkeit führt. Andere Transportprotokolle als TCP sind denkbar, aber wenig verbreitet. Datagram Sockets arbeiten üblicherweise über UDP, also verbindungslos. Dies impliziert Datenaustausch mit geringer Latenz, jedoch geringe Verlässlichkeit. Auch hier sind natürlich alternative Protokolle möglich.
[Bearbeiten] Server Sockets
Ein Socket ist normalerweise die Verbindungsstelle zu einem bestimmten entfernten Programm, repräsentiert durch dessen Adress-Information (z. B. IP-Adresse und Portnummer). Dem Socket selbst ist natürlich auch die eigene Adress-Information zugeordnet.
Ein Server muss jedoch auf Anfragen von unbekannten Rechnern warten können. Er kann sich auf eine bestimmte Adresse binden und auf Anfragen an diese Adresse warten. Allerdings muss ein Server auch auf vielen Adressen Anfragen bearbeiten können. Um dies effizienter zu gestalten, gibt es bei einigen Protokollen auch eine sogenannte Wildcard Adresse, bei der ein oder mehrere Teile der Adress-Information nicht spezifisch sind. Im Beispiel von TCP/IP und UDP/IP ist bei einer Wildcard-Adresse nur die Port-Nummer relevant, es wird eine spezielle (ungültige) IP-Adresse angegeben, um zu signalisieren, dass Verbindungen auf allen IP-Adressen akzeptiert werden sollen.
Wenn der Server eine Anfrage von einem Client erhält, dann wird vom Server-Socket die „normale“ Socket-Verbindung abgeleitet. Das heißt, dass der ursprüngliche Server-Socket erhalten bleibt und weiterhin auf neue Verbindungen wartet während ein neuer, auf den bestimmten Client gerichteter Socket geöffnet wird, der nur für die Kommunikation mit diesem einen Client verwendet wird. Dieser bleibt solange bestehen, bis die Verbindung zum Client von einer der beiden Seiten beendet wird.
Unterschiede beim Aufbau von Sockets auf Client- bzw. Server-Seite:
Client-seitig:
- Socket erstellen
- Erstellten Socket mit der Server-Adresse verbinden, von welcher Daten angefordert werden sollen
- Senden und Empfangen von Daten
- Verbindung trennen, Socket schließen
Server-seitig:
- Server-Socket erstellen
- Binden des Sockets an eine Adresse (Port), über welche Anfragen akzeptiert werden
- Auf Anfragen warten
- Anfragen akzeptieren und damit einen neuen Socket für diesen Client erstellen
- Bearbeiten der Client-Anfrage auf dem neuen Client-Socket
- Client-Socket wieder schließen.
[Bearbeiten] Socket-Programmierung in Java
Java als plattformunabhängige Programmiersprache unterstützt im Paket java.net
unmittelbar die Socket-Programmierung. Das zeigt die Betriebssystemunabhängigkeit des Socket-Konzeptes. Die Implementierung der Sockets für die verschiedenen Plattformen (Linux, Windows, Spezialsysteme) erfolgt in der Klassenbibliothek der virtuellen Maschine.
Die Klassen für die Socket-Programmierung sind Socket
und ServerSocket
. Folgendes Kurzbeispiel zeigt die Verwendung:
ServerSocket serverSocket = new ServerSocket(port); //Serversocket mit bestimmter Port-Nummer erstellen while(true) { Socket clientSocket = serverSocket.accept(); //auf Anfragen warten InputStream input = clientSocket.getInputStream(); //InputStream-Objekt öffnen int data = input.read(); //Daten lesen clientSocket.close(); //Verbindung schließen }
Weiterhin gibt es in der aktuellen Java-Version die Möglichkeit, Sockets über die NewIO-(nio)-Bibliothek anzusprechen. Der Code ist etwas aufwändiger, kann jedoch schneller ausgeführt werden. Das Multiplexing mehrerer Sockets geschieht über einen so genannten Selector (vergleichbar dem Unix-Systemaufruf select).