1 Advanced Network Programming Inhalt Netzwerkkommunikation Protokolle Verbindungsaufbau, -kontrolle, Datentransfer Socketprogrammierung TPC und UDP Client- und Serversockets verbindungsorientierte Server ein einfacher Server für Telefonnummern Datagramm Server ein Spruch-des-Tages-Server Threading a Server
client (Webbrowser) Netzwerkprotokolle 2 GET / HTTP/1.1 Host: localhost Server (Webserver) Anwendungsschicht http, smtp textbasierte Kommunikation ftp etc. HTTP/1.1 200 OK Date: Web, 03 May 2000 19:41:20 GMT Server: Apache/1.3.9 (Unix) Last Modified: Wed, 20 May 1998 14:59:42 GMT ETag: "4405 656 3562efde" Accept Ranges: bytes Content Length: 1622 Content Type: text/html request / response zwischen Client-Rechner und Server-Rechner Netzwerkschicht TCP, UDP
3 Das Packet java.net u.a. URL zur Adressierung Resource im Netzwerk Statusabfrage Aufbau eines I/O-Streams Socket kapselt die Client-Seite einer Kommunikationsverbindung zwischen zwei Programmen im Netzwerk connect to a running server ServerSocket kapselt die Server-Seite einer Kommunikationsverbindung zwischen zwei Programmen im Netzwerk DatagramSocket einfaches Versenden und Empfangen von Datagrams
4 java.net-klassen
5 Java Klasse InetAddress Objekte kapseln IP-Adressen Methoden u.a.: public static InetAddress getbyname(string host) throws UnknownHostException liefert die IP-Adresse bei gegebenen Host-Namen public static InetAddress[] getallbyname(string host) throws UnknownHostException Given the name of a host, returns an array of its IP addresses, based on the configured name service on the system. public static InetAddress getlocalhost() throws UnknownHostException liefert die IP-Adresse von localhost
6 Beispiel zur Verwendung Domain-Name und eigene IP-Adresse anzeigen: import java.net.*; public class MyAddress { } public static void main(string[] args) { } try { InetAddress a = InetAddress.getLocalHost(); System.out.println("Domain-Name: " + a.gethostname()); System.out.println("IP-Adresse: " + a.gethostaddress()); } catch (UnknownHostException e) { } e.printstachtrace();
7 Java Klasse java.net.url URL Uniform Resource Locator http://www.hs-owl.de/fb5/ldv/index.html Protokoll domain name Pfad Dokument zwei komfortable Klassen in java.net: zunächst Instanz der Klasse URL initialisieren URL meinurl = new URL( http://www-server/pfad/dokument.htm); danach mit openconnection() eine Verbindung aufbauen URLConnection urlcon = meinurl.openconnection();
8 Zugriff auf Dateien mittels URL über die Stream-Verbindung kann das Dokument vom Web- Server gelesen werden mit Methoden aus dem Package java.io Methode getinputstream() liefert Datei-Objekt von dem zeilenweisen gelesen werden kann: import java.net.*; import java.io.*;... // define a class... try { // Warum? // create URL-object URL murl = new URL( http://www-server/pfad/ Dokument.html ); // create connection to remote document URLConnection urlcon = murl.openconnection(); // connect a stream for data input DataInputStream dis = new DataInputStream( urlcon.getinputstream());
9 Zugriff auf Dateien mittels URL (2) try { // Warum? // create URL-object URL murl = new URL( http://www-server/pfad/ Dokument.htm ); // create connection to remote document URLConnection urlcon = murl.openconnection(); // connect a stream for data input DataInputStream dis = new DataInputStream( // read contents with readline()... // display contents... urlcon.getinputstream()); } catch (MalformedURLException e) {// invalid URL format System.out.println(e); } catch (IOException e) { // i/o error } System.out.println(e);
10 Lesen von Objekten aus einer URL- Verbindung Methode getcontent() URL murl = new URL( http://www-server/pfad/ Bild.gif); URLConnection urlcon = murl.openconnection(); Object someobject = murl.getcontent(); if (someobject instanceof java.awt.image) System.out.println( Das ist ein Bild ); Methode getcontentlength() liefert - falls möglich - die Länge des Dokuments zurück Methode getcontenttype() liefert - falls möglich - die Typ des Dokuments zurück falls nicht bekannt, wird null zurückgegeben URL Kommunikation funktioniert mit gängigen Protokollen http, ftp, telnet,...
11 Sockets Ein Socket (engl. für Steckdose) ist eine Software- Abstraktion der Netzwerkschnittstelle an jedem Ende einer Netzwerkverbindung ist ein Socket-Objekt erforderlich Prozess Sockets Bindung Ports Es gibt Socket für verschiedene Aktivitäten: Client Socket Verbindet mit einem Server-Dienst Server Socket stellt einen Dienst im Netzwerk zur Verfügung... und verschiedene Verbindungsarten UDP Kommunikation mit Datagrammen, unidirektional TCP verbindungsorientierte Kommunikation über Streams, bidirektional
12 Socketprogrammierung Besonderheit von Java eingebaute Netzwerkunterstützung via Sockets Client Host Internet 79 finger server Client 80 http server Client
13 Klasse java.net.socket für Clienten, die sich mit einem Server verbinden wollen Konstruktor zur Verbindung zum Server mit Adresse servadr und Port servport: Socket( InetAddress servadr, int servport) Meist ist der Port auf dem Client beliebig. Es wird einfach ein freier Port benutzt. Methoden zum Senden von Daten an den Server OutputStream getoutputstream() throws IOException zum Empfangen von Daten vom Server InputStream getinputstream() throws IOException zum Abbau der Verbindung void close() throws IOException
14 Beispiel zur Verwendung Lesen von einem Web-Server: class HTTPGet { public static void main (String[] args) throws Exception { if (args.length!= 2) { System.out.println ("Usage: java HTTPGet host path"); } else { String hostname = args[0]; String path = args[1]; Socket s = new Socket (hostname, 80); PrintWriter out = new PrintWriter (s.getoutputstream (), true); // send request out.print ("GET "+path+" HTTP/1.1\r\n"); out.print ("Host: "+hostname+"\r\n"); out.print ("\r\n"); // read & echo response System.out.println ("--------------------------------------"); in = new BufferedReader (new InputStreamReader (s.getinputstream ())); String line = in.readline (); while (line!= null) { } } } } System.out.println (line); line = in.readline (); System.out.println("--------------------------------------");
15 Aufbau eines Servers Server haben in der Regel kein User Interface werden beim Systemstart aktiviert Programmierung eines verbindungsorientierten Servers benutzt TCP/IP-Packets Vorgehensweise: einen noch nicht benutzten Port auswählen ein ServerSocket-Objekt für diesen Port erzeugen die accept-methode des Objekts aufrufen accept() blocked bis sich jemand mit dem Port verbindet bei einer Verbindung gibt accept() ein Socket-Objekt zurück für die Kommunikation über die nun bestehende Socketverbindung muß ein Protokoll festgelegt werden mit Hilfe des Socket-Objekt InputStream- und OutputStream-Objekte erzeugen
16 Aufbau eines Server-Clients Clients haben meistens ein User Interface Vorgehensweise Rechnername oder -IP-Adresse des Servers herausbekommen Portnummer herausbekommen dort horcht der Server das Kommunikationsprotokoll muß bekannt sein diese Informationen dem Konstruktor eines Socket- Objekts übergeben falls es möglich ist, Informationen zum Server zu senden, einen OutputStream von Socket-Objekt anfordern InputStream vom Socket-Objekt anfordern lesen/schreiben nach Maßgabe des Protokolls
17 Kommunikation mit Datagrams Datagrams UDP-Pakete weniger Overhead aber benutzte Klassen kein Verbindungsstatus richtige Reihenfolge der Zustellung wird nicht garantiert DatagramSocket benutzen Client und Server Server muß Port angeben, beim Client kann er weggelassen werden (dynamische Zuordnung) DatagramPacket Container für Byte-Array der zu übertragenden Info Adresse und Portnummer des Empfängers
18 Aufbau eines Datagram-Servers Vorgehensweise: ein DatagramSocket-Objekt für einen unbenutzten Port erzeugen in einer Programmschleife: ein DatagramPacket-Objekt erzeugen und dem Konstruktor einen Byte-Puffer für die Paketdaten übergeben DatagramSocket-Objekt.receive() aufrufen Methode blockiert bis sich jemand mit dem Port verbindet DatagramPacket-Objekt.getAddress() aufrufen liefert Adresse des Client DatagramPacket-Objekt.getPort() aufrufen ein neues DatagramPacket-Objekt erzeugen und dem Konstructor Sendedaten, Port und Clientadresse übergeben Ende der Schleife
19 Aufbau eines Datagram-Clients Vorgehensweise: ein DatagramSocket-Objekt erzeugen ein DatagramPacket-Objekt erzeugen und dem Konstruktor einen Byte-Puffer mit den Sendedaten, ein InetAddress- Objekt mit der Serveradresse und die Portnummer des Servers übergeben DatagramSocket-Objekt.send() aufrufen Methode blockiert nicht ein weiteres DatagramPacket-Objekt erzeugen und dem Konstruktor einen Byte-Puffer für die Empfangsdaten übergeben DatagramSocket-Objekt.receive() aufrufen auf die Antwort vom Server warten DatagramPacket-Objekt.getData() aufrufen Empfangsdaten verarbeiten
20 Threading a Server ermöglicht es einem Server, mehrere Requests auf einmal zu bearbeiten jeder Request wird in einem eigenen Thread abgearbeitet potentielles Problem der Resourcenbedarf des Servers steigt mit steigender Belastung stark an siehe Text Connection Scaling in Java Ein Thread ist ein innerhalb eines Programms asynchron ablaufender Handlungsfaden (= asynchron ablaufende Methode). Threads ermöglichen das multitasking innerhalb von Anwendungsprogrammen. Java unterstütz die Thread-Programmierung durch eine API-Klasse Thread und das Interface Runnable.
21 Intermezzo ein Ausflug zum Thema Threads Dokumente: JPG 14 Threads JPG 15 Threads im Einsatz
22 Resourcenverbrauch beim Threading Ein normaler Server bearbeitet N parallel eintreffende Clientanfragen in N unabhängigenthreads jeder Thread beansprucht Speicherplatz - einmal Programmcode und Daten - und für den Thread-Stack bei Windows wird für jeden Thread 1 Megabyte Stach- Speicher reserviert Frage: Wofür ist der Stackspeicher da? bei tausenden von gleichzeitigen (concurrent) Verbindungen kann der zur Verfügung stehende Virtual Address Space nicht mehr ausreichen! maximal 2 GByte Virtual Address Space bei 32-Bit- Windows deshalb gibt es das Java-Package java.nio (new I/O) java.nio enthält Klassen, die nicht blockierende (nonblocking) I/O-Operationen unterstützen. Damit ist es möglich, mehrere Clientanfragen quasi gleichzeitig innerhalb eines Threads zu verarbeiten.
23 Ein Multi-Threaded Server Beispiel (1) public ClassServerMulti(String datafile) { fillvectors(datafile); try { ServerSocket classsocket = new ServerSocket(11000); while (true) { Socket clientsocket = classsocket.accept(); new ClassRequestBroker(clientSocket, guys, girls, unsure).start(); } } catch (Exception e) {}... } public ClassRequestBroker(Socket clientsocket, Vector guylist, Vector girllist, Vector unknownlist) extends Thread { Vector guys = guylist; Vector girls = girllist; Vector unsure = unknownlist; Socket requestor = clientsocket; }
24 Multi-Threaded Server Beispiel (2) public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(requestor.getInputStream())); PrintWriter ps = new PrintWriter(requestor.getOutputStream()); ps.println("welcome to the Java class info server."); ps.println("type \"all\" for a list of all students,"); ps.println("type \"guys\" for a list of all male students,"); ps.println("type \"girls\" for a list of all female students."); String request = ""; boolean connected = true; while (connected) { request = br.readline(); if (request.touppercase().equals("quit")) connected = false;
25 Multi-Threaded Server Beispiel (3) } else { if (request.touppercase().equals("guys")) listmalestudents(ps); else if (request.touppercase().equals("girls")) listfemalestudents(ps); else if (request.touppercase().equals("all")) { listmalestudents(ps); listfemalestudents(ps); } else ps.println("\"" + request + "\" not understood"); } } br.close(); ps.close(); requestor.close(); } catch (IOException e) { }