Kommunikation im TCP/IP-Netzwerk
Das Netzwerk verbindet zwei oder mehr Computer. Heutzutage werden Netzwerke eigentlich nur noch unter dem Protokoll TCP/IP organisiert.Die Computer im Netzwerk werden als Hosts bezeichnet und mit einer Adresse oder einer IP-Adresse eindeutig bezeichnet.
Tatsächlich kommunizieren aber nicht Computer, sondern Prozesse. Ein Prozess, der über das Netzwerk kommunizieren will, eröffnet einen Port und ist damit von anderen Hosts eindeutig erreichbar.
Ein typischer HTTP-Server fordert den Port 80 an und ist beispielsweise unter dem Namen meinserver unter der IP-Adresse 192.168.1.20 im Netzwerk zu erreichen. Dann würde ein Browser ihn unter der URL 192.168.1.20:80 oder meinserver:80 erreichen können. Da Webserver aber üblicherweise unter 80 erreichbar sind, kann man den Port weglassen.
Auch ein Browser verwendet einen Port, da er vom Server ja eine Antwort erwartet. Dieser Port muss aber bei jedem Aufruf neu sein, ist also nicht festgelegt und wird vom System bei jeder Anforderung neu und mehr oder weniger zufällig vergeben.
Client-Server
Ein Prozess eröffnet die Netzwerkkommunikation und verbindet sich mit einem anderen Prozess, der auf eine Anfrage wartet.
- Der anfragende Prozess wird als Client bezeichnet.
- Der auf Anfragen wartende Prozess wird Server genannt.
Ein Client mit dem Java-Socket
Das folgende Programm stellt einen einfachen Socket-Client dar. Im Gegensatz zur direkten API unter C stellt Java allerdings kein send und receive zur Verfügung, sondern baut einen STream darüber.Man sieht aber sehr schön, wie über den Aufruf connect eine Verbindung zum Server aufgebaut wird. Anschließend sendet der Client eine Anfrage an den Server auf dem Balkon. Eine solche Sendung blockiert den Client nicht.
Im nächsten Schritt wartet der Client auf die Antwort vom Server. Dieser Lesevorgang, der in der Original-API ein receive oder read stoppt den Client so lange, bis er eine Antwort erhält.
import java.io.DataInputStream; import java.io.IOException; import java.io.PrintStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.UnknownHostException; public class SocketClient { public static void main(String args[]) { String host = "127.0.0.1"; int port = 33033; try { Socket socket = new Socket(); //socket = new Socket(host, port); SocketAddress adresse = new InetSocketAddress(host, port); socket.connect(adresse); PrintStream output = new PrintStream(socket.getOutputStream()); output.println("Hab' mich lieb, Julia!"); DataInputStream input = new DataInputStream(socket.getInputStream()); String str = input.readLine(); System.out.println(str); input.close(); output.close(); socket.close(); } catch(UnknownHostException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } }
Ein Server auf der Basis von ServerSocket
Während in der Standard-API auch der Server einen normalen Socket verwendet, der allerdings an einen speziellen Port gebunden wird, verwendet Java einen speziellen ServerSocket. Dieser erhält den Port, an den er sich bindet bereits über den Konstruktor.Mit dem Aufruf von accept wird ein normaler Socket abgespalten, der dann die eingehenden Daten des Clients empfängt. Solange es keine Anfrage gibt, blockiert der Server.
Er liest nun die Daten und sendet seine Antwort. Sobald er das getan hat, wiederholt er die Schleife und steht wiederum blockiert im accept
import java.io.DataInputStream; import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; public class SocketServer { public static void main(String args[]) { try { ServerSocket server = new ServerSocket(33033); while (true) { Socket socket = server.accept(); DataInputStream input = new DataInputStream(socket.getInputStream()); String str = input.readLine(); System.out.println(str); PrintStream output = new PrintStream(socket.getOutputStream()); output.println("Du mich auch, Romeo!"); input.close(); output.close(); socket.close(); } // server.close(); } catch (IOException e) { e.printStackTrace(); } } }