Client-Server TCP/IP - Kodierung
Die klassen Ein (engl. Sockel) ist eine bidirektionale Netzwerk-Kommunikationsschnittstelle, deren Verwaltung das Betriebssystem übernimmt. Die Kombination aus IP-Adresse und einer Portnummer (RFC 793,original TCP Spezification) Die Kommunikation findet zwischen einem Server und einem Client über einen definierten Port statt. Java hat vordefinierte Klassen in dem Packet java.net, die die Funktionalität bereitstellen Die beiden Schlüsselklassen für die Erstellung von Server-Client-Programme sind: Server
Prinzip der programmierung
Ablauf eines -Programms Bytes Server Server (1024) Bytes ("128.250.25.158", 1024) Client InputStream OutputStream
Server-Kodierung I 1. 2. 2. 3. Server serversocket = new Server(1024); Öffnet einen Server um einem bestimmten Port zu nach Anfragen zu lauschen socket = serversocket.accept(); Ist eine Verbindungsanfrage da, wird ein neuer erstellt, durch den der Server die Daten mit dem Client durch Input-und Outputstreams austauscht: accept() gibt den zurück, der die Verbindung zum Server herstellt outputstream = socket.getoutputstream(); Öffnen des Outputstreams
Server-Kodierung II 4. outputstream.write(255); Durch Ausgabestream einen Wert zum Clienten senden 5. outputstream.close(); Ausgabestream schließen 6. socket.close(); schließen
Client-Kodierung I 1. 2. socket = new ("localhost",1024); Erstellt einen neuen localhost ist der aktuelle PC und kann(muss) durch die IP-Adresse ersetzt werden, wenn die Kommunikation über mehrere PCs geht inputstream = socket.getinputstream(); Erstellt einen neuen Inputstream In der Regel auch einen Outputstream 2. 3. zahl = inputstream.read(); Liest die ankommenden Daten in eine Variable ein
Client-Kodierung II 4. inputstream.close(); Schließt den Inputstream(evtl. auch Outputstream) 5. socket.close(); Schließt den
Arten von s Client Server Server serversocket = new Server(1024); Horcht auf eingehende Verbindungsanfragen von Clients Fordert die Verbindung an und sorgt für Datenaustausch socket = new ("localhost",1024); socket = server.accept(); Erstellt die Verbindung und sorgt für Datenaustausch
Einführungsbeispiel Server-Client: Server Server serversocket = null; socket = null; OutputStream outputstream = null; try { serversocket = new Server(1024); while(true) { System.out.println("Warte auf Client..."); socket = serversocket.accept(); System.out.println("Bin mit Client verbunden."); outputstream = socket.getoutputstream(); outputstream.write(255); outputstream.close(); socket.close(); } } Deklarieren und initialisieren der Objekte Erstellt einen Server gebunden an Port 1024 Unendliche Wiederholungsanweisung für ankommende Nachrichten lauscht auf dem Port 1024 auf ankommende Nachrichten Sendet 255 an den Klienten(der den Wert in die Konsole schreibt) Schließen des s der Nachricht ->Aufgabe 1
Einführungsbeispiel Server-Client: Client socket = null; InputStream inputstream = null; int zahl; try { socket = new ("localhost",1024); inputstream = socket.getinputstream(); zahl = inputstream.read(); System.out.println(zahl ); inputstream.close(); socket.close(); } Deklarieren und initialisieren der Objekte Erstellt einen Server gebunden an Port 1024 der durch localhost an den gleichen Rechner sendet! Liest einen InputStream für das Einlesen der Daten(Byte) aus dem InputStream Schliessen des InputStreams und des s
DataInputStream - Client - Server Kodierung I my = new ( localhost,1024); DataInputStream input = new DataInputStream(socket.getInputStream()); Die Klasse DataInputStream erlaubt ganze Zeilen von Text sowie primitive Datentypen zu lesen. Sie haben Methoden wie read, readint, readdouble und readline
DataInputStream - Client - Server Kodierung II my = new ( localhost,1024); DataOutputStream output =new DataOutputStream(socket.getOutputStream ()); PrintStream output = new PrintOutputStream(socket.getOutputStream()); Die Klasse PrintStream erlaubt ganze Zeilen von Text sowie primitive Datentypen zu schreiben mit den Funktionen write() und println(). Die Klasse DataOutputStream erlaubt nur primitive Datentypen zu schreiben wie z.b. writebytes() Weitere Informationen zu Streams finden sich unter: http://tutorials.jenkov.com/java-io/datainputstream.html
DataInputStream - Client - Server Kodierung II my = new ( localhost,1024); DataOutputStream output =new DataOutputStream(socket.getOutputStream ()); PrintStream output = new PrintOutputStream(socket.getOutputStream()); Die Klasse PrintStream erlaubt ganze Zeilen von Text sowie primitive Datentypen zu schreiben mit den Funktionen write() und println(). Die Klasse DataOutputStream erlaubt nur primitive Datentypen zu schreiben wie z.b. writebytes() Weitere Informationen zu Streams finden sich unter: http://tutorials.jenkov.com/java-io/datainputstream.html 0 1f
Port Scanner try { socket = new ("localhost",i); System.out.print(" Hier laeuft ein Server!"); socket.close(); } catch(ioexception e){ } Versuchen zum Server Verbindung herzustellen Evtl. Fehlermeldung 0 3
Ermitteln von IP und Portadresse von Client/Server System.out.println ("Server kontaktiert: " + server.getinetaddress() + server.getport()); Parameter des Kommunikationspartners System.out.println ("Server kontaktiert: " + server.getlocaladdress() + server.getlocalport()); Eigene Parameter 0 4
Echo-Server I - Prinzip 1024 Echo- Server "128.250.25.158", 1024 Hello Echo! Echo- Client "128.250.25.158", 1024 Server BufferedReader PrintWriter InputStream OutputStream Hello Echo!
Echo-Server II Senden & Empfangen strfromandtoclient = bufferedreader.readline(); printwriter. println(strtoserver); printwriter.println(strfromandtoclient); strfromserver = bufferedreader.readline();
Echo-Server III BufferedReader(analog BufferedWriter) InputStream inputstream = socket.getinputstream(); InputStreamReader inputstreamreader = new InputStreamReader( inputstream ); BufferedReader bufferedreader = new BufferedReader( inputstreamreader ); bytes Input Stream bytes Input Stream Reader chars Buffered Reader chars Lokal/Unicode Kodierung Puffer BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Echo-Server IV Methoden von BufferedWriter Google: BufferedWriter Oracle 0 5
Echo-Server mit Threads I - Motivation Der Echo-Server kann nur mit einem Klienten kommunizieren. Erst wenn dieser sich abgemeldet hat, dann kann der nächste sich anmelden, wenn der Server wieder bei der Methode accept() angelangt ist Lösung: Threads, wo jeweils ein Thread mit einem Clienten kommuniziert Regel: Threads werden eingesetzt, sobald ein Prozess sich an mehreren Stellen in seinem Programmablauf "gleichzeitig" aufhalten soll
Echo-Server mit Threads II - Prinzip Server accept() Thread Thread Thread
Echo-Server mit Threads III - Kodierung Server server = new Server( ); while (true) { socket = server.accept(); new Thread(socket).start(); } Thread 0 6
MultiChat-Server mit Threads Prinzip Server Server accept() add() get() Thread write() ArrayList <Thread> write()
MultiChat-Server mit Threads Kodierungs Tricks - Server arrthreads=new ArrayList<ChatServerThread>(). ChatServerThread thdchatserver=new ChatServerThread(socket, arrthreads);. arrthreads.add(thdchatserver); ChatServer public class ChatServerThread extends Thread{ private ArrayList<ChatServerThread> arrthreads;. ChatServerThread( socket,arraylist<chatserverthread> arrthreads){ this. arrthreads=arrthreads; } ChatServerThread Kopie der Adresse Übergabe der Adresse
MultiChat-Server mit Threads Prinzip Client Echo-Client: Chat-Client: Schreiben Schreiben Lesen Lesen 0 7
Abiturklassen und Server Server - - C + + localport: int server: Server Server(localPort:int) accept(): close() - - - - C C + + + + + + + + + hostname: String port: int socket: reader: BufferedReader (hostname: String, port:int) (socket: ) close() connect(): boolean dataavailable(): int read():int read(b: byte[], len:int):int readline(): String write(b: int) write(b: byte[], len:int) write(s: String) 0 8
Abiturklassen und Server - Probleme socket = new ("127.0.0.1", 9999); socket = new ("127.0.0.1", 9999); if (socket.connect()){ // Connection Action } Es muss für eine Verbindung connect aufgerufen werden!
Abiturklassen und Server Probleme II try{ } catch{ } Konsequenterweise braucht die -Klasse kein try-catch, die Server-Klasse aber schon!
Abiturklassen und Server Probleme III socket.write(msgfromclient+"\n"); Es gibt keine writeline analog zu readline! Konsequenz: Ohne \n bleibt das Programm beim nächsten readline hängen!