Menu Content/Inhalt
Startseite arrow Java arrow Socket-Programmierung in Java
Socket-Programmierung in Java Drucken E-Mail

Warum Socket-Programmierung?

Sobald man Programme schreiben will, die nicht auf einem einzigen Rechner gespeichert sind, sondern auf mehrere beliebige Standorte, die miteinander vernetzt sind, verteilt sein können, muss man sich Gedanken darüber machen, wie die einzelnen Programmteile miteinander kommunizieren können. Eine schon recht alte, aber immer noch häufig verwendete Methode ist die Kommunikation über Sockets. Hierbei agiert das Programmteil, das einen Dienst anbietet als Server, das andere als Client.

Java stellt mittlerweile einige recht komfortable Klassen zur Socket-Programmierung zur Verfügung. Das Package java.net enthält die folgenden zwei Socket-Klassen:

  • ServerSocket
  • Socket (hiermit ist immer der Client-Socket gemeint)

Neben den Socket-Klassen benötigt man für die Kommunikation über Streams folgende zwei Stream-Klassen aus dem Package java.io:

  • OutputStream
  • InputStream

Mit diesen zwei Klassen lassen sich allerdings nur Interger-Zahlen übertragen. Falls man beliebige Objekte mit Streams übertragen möchte, braucht man aus java.io auch noch:

  • ObjectOutputStream
  • ObjectInputStream

Das Einleiten vom Aufbau einer Socket-Verbindung ist immer die Aufgabe des Clients. Solange noch keine Verbindung besteht, hat der Server die Aufgabe, auf einem bestimmten Port zu hören, ob sich dort ein Client mit ihm verbinden will. Das folgend Aktivitäts-Diagramm veranschaulicht die Situation.

 

 

Einige wichtige Server-Methoden

Signatur / Aufruf
Parameter
Erklärung
Exceptions
Package / Klasse
ServerSocket(int port)


Port, auf dem auf einen Client-Anfrage gewartet werden soll es wird ein Server erzeugt, der auf dem übergebenen Port auf Clients wartet IOException

java.net / ServerSocket

Socket accept()   nachdem eine Client-Anfrage eingetroffen ist besteht beim Server die Möglichkeit, die Verbindung zu akzeptieren IOException java.net / ServerSocket
void setSoTimeout(int timeout)

Wartezeit in Milli-Sekunden gibt eine bestimmte Zeit vor, nach der das Warten auf Client-Anfragen gestoppt wird SocketException java.net / ServerSocket
close()   das Warten auf Client-Anfragen wird beendet IOException java.net / ServerSocket

 

 

Einige wichtige Client-Methoden der Klasse Socket

Signatur / Aufruf
Parameter
Erklärung
Exceptions
Package / Klasse
Socket(String host, int port)

host: der Host auf dem sich der Server befindet

port: Port, auf dem der Server auf eine Verbindung wartet
Konstruktor:
Erzeugt einen Stream-Socket und verbindet diesen mit dem angegebenen Port auf dem angegebenen Host
IOException java.net / Socket
Socket(InetAddress address, int port)

host: IP vom Host auf dem sich der Server befindet

port: Port, auf dem der Server auf eine Verbindung wartet
Konstruktor:
Erzeugt einen Stream-Socket und verbindet diesen mit dem angegebenen Port auf der angegebenen Adresse. Dieser Konstruktor kann anstelle des vorherigen aufgerufen werden, wenn man anstelle des Hostnamens nur dessen IP hat.
IOException java.net / Socket
void flush()   Damit beim Senden über eine Socket-Verbindung alles gesendet wird und nichts zwischengepuffert wird, sollte man grundsätzlich nach dem Senden diese Methode aufrufen. IOException

java.io / OutputStream

java.io / InputStream

void close()   zum Schliessen einer Socket-Verbindung IOException java.net / Socket
String getHostName()   liefert den Namen des Hosts - java.net / Socket
InetAddress getLocalHost()   liefert die IP des eigenen Hosts UnknownHostException java.net / Socket
InputStream getInputStream()   liefert einen InputStream, den man braucht, um Daten über eine Socket-Verbindung empfangen zu können IOException java.net / Socket
OutputStream getOutputStream()
  liefert einen OutputStream, den man braucht, um Daten über eine Socket-Verbindung verschicken zu können IOException java.net / Socket

 

Java-Code eines Servers

Der folgende Java-Code implementiert einen Server, der auf Port "1234" auf Anfragen von Clients wartet. Der Server hat die Aufgabe, 2 Zahlen die der Client über die Socket-Verbindung schickt zu addieren und das Ergebnis zurück zu schicken.

Es müssen grundsätzlich beide im Bild angegebenen Pakete importiert werden.

Die Main-Methode startet den Server. Dadurch wird als Attribut die neue Socket-Verbindung "server" angelegt und im Konstruktor in eine Endlosschleife gegangen, wo vorerst mal in Zeile 10 angehalten und auf Nachrichten vom Client gewartet wird.



Beschreibung des Codes:

  • solange auf Port 1234 nichts zu hören ist wartet der Server auf Anfragen (10)
  • sobald ein Client eine Zahl schickt wird eine Verbindung aufgebaut (10 - 12)
  • zwei gesendete Zahlen werden eingelesen (13, 14)
  • die Summe beider Zahlen wird als Antwort über die Verbindung übermittelt (15)
  • alle gepufferten Bytes abschicken (16)
  • Eingabe und Ausgabestrom schliessen (17, 18)
  • warten auf weitere Client-Anfragen (10)

 

Java-Code eines Clients

Jetzt wird ein möglicher Client implementiert, der den Dienst des Servers aus dem Beispiel oben nutzt. Der Client hat die Aufgabe eine Socket-Verbindung zum Server aufzubauen, diesem die Zahlen 5 und 10 zu übermitteln, die Antwort des Servers zu empfangen und diese auf der Konsole auszugeben. Danach soll die Verbindung geschlossen werden und der Client soll beendet werden (automatisch, weil alles abgearbeitet wurde).

Die Main-Methode startet wieder nur den Client. Es muss natürlich bedacht werden, dass zuerst der Server gestartet sein muss, bevor ein Client eine Anfrage an ihn stellen kann. Nachdem der Client alles abgearbeitet hat und es diesen nicht mehr gibt, wartet der Server wieder auf neue Anfragen, weil dieser sich ja in einer Endlosschleife befindet

.java sockets

Beschreibung des Codes:

  • die Verbindung zum Server wird hergestellt (7 - 9)
  • zwei Zahlen werden über die Verbindung übermittelt (10, 11)
  • der Ausgabepuffer wird geleert (12)
  • das Ergebnis wird von der Eingabe gelesen und auf die Konsole geschrieben (13)
  • die Verbindung zum Server wird beendet (14)
  • Eingabe und Ausgabestrom schliessen (15, 16)