Forschungszentrum Karlsruhe Technik und Umwelt Client-Server Kommunikation Die Socket Schnittstelle Clemens Düpmeier, 16.05.2016 -1- Forschungszentrum Karlsruhe Technik und Umwelt Kommunikation über Socket API • Rechner kommunizieren heutzutage hauptsächlich über TCP/IP Netze (Inter-/Intranets) • Die in C geschriebene Socket-API ist die (unterste) Betriebssystemschnittstelle zur Kommunikation über TCP/IP Netze • Sockets sind in Analogie zum Umgang mit Dateidatenströmen realisiert Clemens Düpmeier, 16.05.2016 -2- Verbindungsorientierte Kommunikation • Telefonprinzip • Server wartet in accept() (passiv) • Client stellt Verbindung mit connect() her (aktiv) • Server bekommt mit jeder Verbindung neuen Socket für Kommunikation mit speziellen Client • Datenstrom-basierte Kommunikation über send (write) bzw. recv (read) • Kommunikationspartner werden über Kommunikationsfehler informiert Clemens Düpmeier, 16.05.2016 -3- Forschungszentrum Karlsruhe Technik und Umwelt Server-Client Kommunikation Server (passiv) s=socket(...); bind(/* address */); Client (aktiv) s=socket(...); /* no bind */ listen(s,length); for (;;) { new_sock=accept(/*...*/); if (fork() == 0) handle(new_sock); } Clemens Düpmeier, 16.05.2016 connect(s, /* address */); talk_with_server(s); -4- Forschungszentrum Karlsruhe Technik und Umwelt Funktionsweise von accept() Serverrechner Clientrechner Serverprozess Clientprozess Sockets accept Socket nach accept 50167 Netzwerkschnittstelle 80 Netzwerkschnittstelle LAN Clemens Düpmeier, 16.05.2016 -5- Forschungszentrum Karlsruhe Technik und Umwelt Paket-orientierte Kommunikation • Client und Server öffnen UDPSocket • In sendto() bzw. recfrom() Aufrufen werden – Abgeschlossene Datenpakete (Bytearrays) gesendet bzw. empfangen – Dabei wird mit jedem Aufruf die Ziel- bzw. Empfängeradresse kommuniziert • System meldet – Weder Kommunikationsfehler – Noch garantiert es das Ankommen von Paketen bzw. deren Reihenfolge Clemens Düpmeier, 16.05.2016 -6- Forschungszentrum Karlsruhe Technik und Umwelt Eigenschaften der Socket Schnittstelle • Unterste Schnittstelle zum Betriebssystem • Synchronisation der Kommunikation liegt voll beim Anwender • Fehlerbehandlung liegt ebenfalls beim Anwender • Nicht binär transparente Datenübertragung • Nicht objekt-orientiert Clemens Düpmeier, 16.05.2016 -7- Forschungszentrum Karlsruhe Technik und Umwelt SMTP Protokoll $telnet mailhost.iai.fzk.de 25 Trying 141.52.44.1... Connected to mailhost.iai.fzk.de Escape character is '^]'. 220 mailhost.iai.fzk.de sendmail version 10.1 ready at Wed, 6 May 2002 22:52:47 +0200 HELO uisun7.iai.fzk.de 250 mailhost.iai.fzk.de Hello uisun7.iai.fzk.de MAIL From: <[email protected]> 250 Sender OK (verified) RCPT To: <duepmeier> 250 Receiver OK (verified) DATA 354 Start mail input; end with <CRLF>.<CRLF> Subject: Dann wollen wir mal SMTP testen Hier beginnt die eigentliche Nachricht der Mail Dann können auch noch weitere Zeilen folgen, die allerdings mit einem Punkt auf einer einzelnen Zeile enden müssen. . 250 OK QUIT Clemens Düpmeier, 16.05.2016 -8- Forschungszentrum Karlsruhe Technik und Umwelt HTTP Protokoll - Ablauf Anfrage GET /index.html HTTP/1.0 If-Modified-Since: Saturday, 12-Dec-98, 12:34:56 GMT Client Antwort Server HTTP/1.0 200 OK MIME-Version: 1.0 Content-type: text/html Content-length: 123 Last-Modified: Saturday, 12-Dec-98 12:34:56 GMT <HTML>Hier beginnt die eigentliche HTML Datei... Clemens Düpmeier, 16.05.2016 -9- Forschungszentrum Karlsruhe Technik und Umwelt Einige HTTP Clientkommandos • GET Liefert ein Datei vom Server • HEAD Liefert nur Dateiinformationen • POST Sendet Daten (CGI) an den Server • PUT Sendet komplette Dateien an Server • DELETE Löschte Datei vom Server Clemens Düpmeier, 16.05.2016 - 10 - Forschungszentrum Karlsruhe Technik und Umwelt Beispiele für HTTP Requests GET / HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/2.0 (Win95; I) Host: merlin Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* POST /cgi/4848 HTTP/1.0 Referer: http://tecfa.unige.ch:7778/4848 Connection: Keep-Alive User-Agent: Mozilla/3.01 (X11; I; SunOS 5.4 sun4m) Host: tecfa.unige.ch:7778 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* Content-type: application/x-www-form-urlencoded Content-length: 42 name=Ulli&nachname=Ullenboom Clemens Düpmeier, 16.05.2016 - 11 - Forschungszentrum Karlsruhe Technik und Umwelt HTTP Server Statuscodes • 1xx: Informierend, 2xx: Erfolgreich • 3xx: Rückfrage, 4xx: Fehler beim Client • 5xx: Fehler beim Server • 200 202 OK Accepted • 300 302 Multiple Choices 301 Moved Temporarily 304 Moved Permantly Not Modified • 400 403 Bad Request Forbidden 401 404 Unauthorized Not Found • 500 502 Internal Server E. Bad Gateway 501 503 Not Implemented Service Unavailable Clemens Düpmeier, 16.05.2016 201 204 Created No Content - 12 - Forschungszentrum Karlsruhe Technik und Umwelt Java Socket API Clemens Düpmeier, 16.05.2016 - 13 - Forschungszentrum Karlsruhe Technik und Umwelt InetAddress Klasse InetAddress static static … Byte[] … String String … IntetAddress getByName() // erzeuge Adressobjekt InetAddress getLocalHost() // erzeuge Adressobjekt getAddress() getHostName() getHostAddress() Clemens Düpmeier, 16.05.2016 // gebe mir Hostname // gebe mir Adresse - 14 - Forschungszentrum Karlsruhe Technik und Umwelt Beispiel Nutzung von InetAddress public class WhoAmI { public static void main(String args[]) throws Exception { InetAddress myAddress=InetAddress.getLocalHost(); System.out.println("Hostname: " + myAddress.getHostName()); System.out.println("IP Adresse: " + myAddress.getHostAddress()); } } Clemens Düpmeier, 16.05.2016 - 15 - Forschungszentrum Karlsruhe Technik und Umwelt InetSocketAddress Klasse InetSocketAddress (extends SocketAddress) InetSocketAddress(String hostname, int InetSocketAddress(InetAddress address, … InetAddress getAddress() // Hostteil getHostName(): String // gebe mir getPort(): String // gebe mir … Clemens Düpmeier, 16.05.2016 port) int port) als InetAdress Hostname Portnummer - 16 - Forschungszentrum Karlsruhe Technik und Umwelt Client-Server Socketverbindungen in Java Server Applikation Client Anwendung new new Socket Objekt connect() ServerSocket Objekt accept() return Datenaustausch über das Netz Clemens Düpmeier, 16.05.2016 ServerSocket blockiert in accept() bis Client einen Verbindungsaufbau durchgeführt hat Socket Objekt Die beiden Sockets sind nun verbunden - 17 - Forschungszentrum Karlsruhe Technik und Umwelt Socket Klasse Socket Socket() Socket(String host, int port) Socket(InetAddress host, int port) ... void close() void connect(SocketAddress endpoint) Void connect(SocketAddress endpoint, int timeout) … int getPort() InetAddress getInetAddress() … InputStream getInputStream() OutputStream getOutputStream() Clemens Düpmeier, 16.05.2016 - 18 - Forschungszentrum Karlsruhe Technik und Umwelt ServerSocket Klasse ServerSocket ServerSocket() ServerSocket(int port) ServerSocket(int port, int backlog) ... void bind(SocketAddress endpoint) Void bind(SocketAddress endpoint, int backlog Socket accept() void close() … int getLocalPort() InetAddress getInetAddress() … Clemens Düpmeier, 16.05.2016 - 19 - Forschungszentrum Karlsruhe Technik und Umwelt Beispiel TCP Serverapplikation public class MultServer { public static void main(String args[]) throws Exception { ServerSocket server=new ServerSocket(3141); while (true) { Socket client=server.accept(); InputStream in =client.getInputStream(); OutputStream out=client.getOutputStream(); int firstNumber=in.read(); int secondNumber=in.read(); out.write(firstNumber * secondNumber); } } } Clemens Düpmeier, 16.05.2016 - 20 - Forschungszentrum Karlsruhe Technik und Umwelt Beispiel TCP Clientapplikation public class MultClient { public static void main(String args[]) { try { Socket server = new Socket("Hostname", 3141); InputStream in = server.getInputStream(); OutputStream out = server.getOutputStream(); out.write(4); out.write(5); int result=in.read(); System.out.println("4 * 5 = " +result); } catch (IOException e) { System.out.println("Fehler bei Kommunikation"); } } } Clemens Düpmeier, 16.05.2016 - 21 - Forschungszentrum Karlsruhe Technik und Umwelt Gepufferte Ein-/Ausgabe über Sockets Socket t = new Socket(...); .... BufferedReader in = new BufferedReader( new InputStreamReader(t.getInputStream())); PrintStream os = new PrintStream(t.getOutputStream()); ... in.readLine(); ... os.println("Irgendwelche Strings + Objekte mit toString() ausgeben"; ... Clemens Düpmeier, 16.05.2016 - 22 - Forschungszentrum Karlsruhe Technik und Umwelt Client mit zeilenorientierter Kommunikation public class PingClient { public static void main(String args[]) throws Exception { Socket t = new Socket(args[0], 7); BufferedReader in = new BufferedReader( new InputStreamReader(t.getInputStream())); PrintStream out = new PrintStream(t.getOutputStream()); String test= "Hallo aus Karlsruhe, vom " + new Date(); out.println(test); String antwort=in.readLine(); if (antwort.equals(test)) System.out.println("Server lebt"); else System.out.println("Server ist nicht erreichbar"); } } Clemens Düpmeier, 16.05.2016 - 23 - Forschungszentrum Karlsruhe Technik und Umwelt Kommunikation über UDP Applikation new dp Paket enthält neben Daten auch Ziel-IP und Zielportnummer DatagramSocket Objekt new DatagramPacket Objekt (dp) send/receive(dp) Clemens Düpmeier, 16.05.2016 - 24 - Forschungszentrum Karlsruhe Technik und Umwelt DatagramSocket Klasse DatagramSocket DatagramSocket() DatagrammSocket(int port) DatagrmSocket(int port, InetAddress laddr) ... void bind(SocketAddress laddress) void close() void receive(DatagramPacket p) void send(DatagramPacket p) … int getLocalPort() InetAddress getLocalAddress() … Clemens Düpmeier, 16.05.2016 - 25 - Forschungszentrum Karlsruhe Technik und Umwelt DatagramPacket Klasse DatagramPacket DatagramPacket(byte[] buf, int length) DatagrammPacket(byte[] buf, int length, InetAddress addr, int port) ... InetAddress getAddress() void getPort() byte[] getData() void setData(byte[] buf) int getLength() … Clemens Düpmeier, 16.05.2016 - 26 - Forschungszentrum Karlsruhe Technik und Umwelt Beispiel UDPClient public class UDPClient { public static void main(String args[]) throws Exception { DatagramPacket packet; DatagramSocket dSocket = new DatagramSocket(); InetAddress serverAddress=InetAddress.getByName("ServerName"); while (true) { String s = new Date().toString(); packet = new DatagramPacket(s.getBytes(), s.length(), serverAddress, 4711); dSocket.send(packet); System.out.println("Paket " + packet + " abgeschickt"); Thread.sleep(1000); } } } Clemens Düpmeier, 16.05.2016 - 27 - Forschungszentrum Karlsruhe Technik und Umwelt Beispiel UDPServer public class UDPServer { public static void main(String args[]) throws Exception { byte data[] = new byte[1024]; DatagramPacket packet; DatagramSocket socket = new DatagramSocket(4711); while (true) { packet=new DatagramPacket(data, data.length); socket.receive(packet); InetAddress address = packet.getAddress(); int port = packet.getPort(); System.out.println("Paket von " + packet.getAddress() + "am Port " + packet.getPort() + " erhalten"); insertIntoDatabase(packet.getData()); } }} Clemens Düpmeier, 16.05.2016 - 28 - Forschungszentrum Karlsruhe Technik und Umwelt Vorteile Low-Level Client Server • effizient bzgl. Laufzeit • überall verfügbar • standardisiertes Interface • für interne und externe Kommunikation verfügbar Clemens Düpmeier, 16.05.2016 - 29 - Forschungszentrum Karlsruhe Technik und Umwelt Nachteile Low-Level Kommunikation • zu komplex bzgl. der Kommunikationsdetails • Synchronisation/Fehlerbehandlung liegt voll beim Anwendungsprogrammierer • nicht binär-transparent ohne Arbeit • Clients müssen wissen, wo Server sind • Mix von Applikationslogik + Netzwerktransportlogik Clemens Düpmeier, 16.05.2016 - 30 - Forschungszentrum Karlsruhe Technik und Umwelt Client-Server Zugriff auf Datenbanken (am Beispiel von JDBC) Clemens Düpmeier, 16.05.2016 - 31 - Forschungszentrum Karlsruhe Technik und Umwelt Was ist die JDBC API • eigentlich Produktname, aber oft übersetzt als Java Database Connectivity API • API zum Zugriff auf Datenquellen, die eine tabellenartige Struktur haben • Beispiele für Datenquellen sind: – relationale Datenbanken – Dateien mit tabellenartiger Struktur – ODBC Datenquellen unter Windows Clemens Düpmeier, 16.05.2016 - 32 - Forschungszentrum Karlsruhe Technik und Umwelt Typisches Nutzungsschema Connection con = DriverManager.getConnection( "jdbc:myDriver:wombat", "myLogin", "myPassword"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1"); while (rs.next()) { int x = rs.getInt("a"); String s = rs.getString("b"); float f = rs.getFloat("c"); } • Treiber für spezielle Datenquelle laden • Verbindung mit Datenquelle herstellen • Abfrage machen oder Update Operation durchführen • Resultate der Abfrage bearbeiten Clemens Düpmeier, 16.05.2016 - 33 - Forschungszentrum Karlsruhe Technik und Umwelt Typen von JDBC Treibern • JDBC-ODBC Bridge Treiber – nutzt die ODBC API, um auf ODBC Datenquellen zuzugreifen • Native-API Java Treiber – ruft von Java aus Native Datenbank API auf • Netz-Protokoll All-Java Treiber – benutzt Netz-Protokoll, um auf Middleware Server zuzugreifen, der seinerseits auf Datenbank zugreift • Native Protocol All-Java Treiber – direkter Aufruf des Datenbankservers über DBMS Netzprotokoll Clemens Düpmeier, 16.05.2016 - 34 - Forschungszentrum Karlsruhe Technik und Umwelt JDBC-ODBC Datenquelle try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { System.out.println("Konnte JDBC-ODBC Bridge Treiber nicht laden"); return; } Connection con = DriverManager.getConnection( "jdbc:odbc:myDatabase", "myLogin", "myPassword"); • Treiber lassen sich mit Class.forName laden • Oben wird im JDK enthaltener JDBC-OBDC Bridge Treiber geladen • ODBC Datenquellen werden mit jdbc:odbc:Name-der-Datenquelle referenziert Clemens Düpmeier, 16.05.2016 - 35 - Forschungszentrum Karlsruhe Technik und Umwelt JDBC-MSQL Datenquelle try { Class.forName("com.imaginary.sql.msql.MsqlDriver"); } catch (Exception e) { System.out.println("Konnte JDBC Treiber nicht laden"); return; } Connection con = DriverManager.getConnection( "jdbc:msql://machine-name:port#/database-name", "myLogin", "myPassword"); • Treiber lassen sich mit Class.forName laden • Oben Treiber für mSQL Datenbank geladen • Datenquellen werden allgemeiner durch URL's der Form jdbc:subprotocol:subname referenziert Clemens Düpmeier, 16.05.2016 - 36 - Forschungszentrum Karlsruhe Technik und Umwelt DriverManager Klasse DriverManager static Connection getConnection(String url) static Connection getConnection(String url, Properties info) static Connection getConnection(String url, String user, String password) // verschiedene Arten Verbindung aufzubauen ... static void registerDriver(Driver driver) // wird von Treibern zum Registrieren verwendet ... static void setLogWriter(PrintWriter out) // Loggen von Informationen über JDBC Protokollverkehr stativ void println(String message) // Ausgabe von Messagestrings auf Logging Ausgang … Clemens Düpmeier, 16.05.2016 - 37 - Forschungszentrum Karlsruhe Technik und Umwelt Verschiedene Statement-Objekte • Statement Objekt erzeugen Statement stmnt = con.createStatement() • PreparedStatement Objekt erzeugen PreparedStatement pstmnt = con.prepareStatement("...") • CallableStatement Objekt erzeugen CallableStatement cstmnt = con.prepareCall("...") Clemens Düpmeier, 16.05.2016 - 38 - Forschungszentrum Karlsruhe Technik und Umwelt Verwendung der verschiedenen Statement Objektklassen • Statement für einfache Operationen • PreparedStatement Objekte verwenden, wenn SQL Abfragen öfters wiederholt werden • CallableStatement Objekte nutzen, um StoredProcedures auszuführen Clemens Düpmeier, 16.05.2016 - 39 - Forschungszentrum Karlsruhe Technik und Umwelt Datenbankabfrage über Statement Objekt durchführen try { // Statement Objekt über Connection Objekt erzeugen Statement stmt = con.createStatement(); // SQL Abfrage als String definieren String query = "SELECT cityName, Population, Temperature" + " FROM cityTable"; // Abfrage durch Aufruf von Methode executeQuery() durchführen ResultSet rs = stmt.executeQuery(query); // hier nun Ergebnisse durch Auswertung von ResultSet // verarbeiten Clemens Düpmeier, 16.05.2016 - 40 - Forschungszentrum Karlsruhe Technik und Umwelt ResultSet abarbeiten try { ... // Abfrage durch Aufruf von Methode executeQuery() durchführen ResultSet rs = stmt.executeQuery(query); while (rs.next()) { System.out.println("Stadt: " + rs.getString("cityName")); System.out.println("Anzahl Einwohner: " + rs.getLong("Population")); System.out.println("Durchschnittstemperatur: " + rs.getInt("Temperature")); } } catch ... Clemens Düpmeier, 16.05.2016 - 41 - Forschungszentrum Karlsruhe Technik und Umwelt Zugriffsmethoden und SQL Datentypen • • • • • • • • • • • • • • getInt() getLong() getFloat() getDouble() getBignum() getBigDecimal() getBoolean() getString() getString() getAsciiStream() getDate() getTime() getTimestamp() getObject() Clemens Düpmeier, 16.05.2016 INTEGER BIG INT REAL FLOAT DECIMAL NUMBER BIT VARCHAR CHAR LANGVARCHAR DATE TIME TIME STAMP jeder Typ - 42 - Forschungszentrum Karlsruhe Technik und Umwelt Daten in Datenbank einfügen try { // Statement Objekt über Connection Objekt erzeugen Statement stmt = con.createStatement(); // SQL Statement zum Einfügen von Daten definieren String sqlstring = "INSERT INTO cityTable " + "(cityName, Population, Temperature) " + "VALUES (Karlsruhe, 275000, 15)"; // Einfügen mit Aufruf der Methode executeUpdate() durchführen int affectedRows = stmt.executeUpdate(sqlstring); Clemens Düpmeier, 16.05.2016 - 43 - Forschungszentrum Karlsruhe Technik und Umwelt 2-Tier Applikation mit JDBC Datenzugriff Java Applikation Client Maschine JDBC proprietäres Protokoll zu Datenbank Rechner mit Datenbank DBMS Clemens Düpmeier, 16.05.2016 - 44 - Forschungszentrum Karlsruhe Technik und Umwelt Klassische Multitier Architektur Präsentationsschicht Applikationslogik Datenlogik Clemens Düpmeier, 16.05.2016 Datenlogik - 45 - Forschungszentrum Karlsruhe Technik und Umwelt Klassische 3-Tier Architektur mit JDBC Client z.B. Browser Client Maschine HTTP, RMI, CORBA Applikationsserver JDBC Server mit Middle-Tier (Applikationslogik) proprietäres Protokoll zu Datenbank DBMS Clemens Düpmeier, 16.05.2016 Rechner mit Datenbank - 46 - Forschungszentrum Karlsruhe Technik und Umwelt 4-Tier Architektur mit JDBC Client z.B. Browser Client Maschine HTTP Webserver Servlet RMI, CORBA Applikationsserver JDBC Server mit (Applikationslogik) proprietäres Protokoll zu Datenbank DBMS Clemens Düpmeier, 16.05.2016 Rechner mit Datenbank - 47 -