Module M2207 – part. 3 Programmation réseau IUT de Béziers, dépt. R&T © 2009-2017 http://www.borelly.net/ [email protected] Partie Réseau Paquetages : java.net.* (et java.io.*) TCP : classes Socket et ServeurSocket UDP : classes DatagramPacket et DatagramSocket Multicast : DatagramPacket et MulticastSocket SSL/TLS : javax.net.*, javax.net.ssl.*, ... 16/05/17 M2207 - [email protected] 2/15 Exemple de client/serveur TCP Port TCP 7 - RFC 862 Le protocole « echo » ressemble à un ping. Le client envoie une chaîne et le serveur lui renvoie en écho la même valeur. Pour cet exemple, il faudra transformer les flots d'entrée et de sortie de chaque connexion réseau (Socket) en objets permettant d'écrire (PrintStream) ou de lire (BufferedReader) du texte. 16/05/17 M2207 - [email protected] 3/15 La classe Socket (1) La classe Socket donne accès aux flots de données grâce aux méthodes suivantes : OutputStream getOutputStream() InputStream getInputStream() On doit donc chercher des constructeurs compatibles avec ses objets pour manipuler du texte. Pour la classe PrintStream, il n'y a pas de soucis car il existe au moins 2 constructeurs correspondant : 16/05/17 PrintStream(OutputStream out) PrintStream(OutputStream out, boolean autoFlush) M2207 - [email protected] 4/15 La classe Socket (2) Pour la classe BufferedReader, il y a un petit soucis car les constructeurs utilisent des objets Reader : Il faut donc passer par un intermédiaire pour transformer un InputStream en Reader afin d'obtenir l'objet BufferedReader. Cela se fait avec la classe InputStreamReader : BufferedReader(Reader in) InputStreamReader(InputStream in) On obtient donc : InputStream is=sock.getInputStream(); InputStreamReader isr=new InputStreamReader(is); BufferedReader sockIn=new BufferedReader(isr); 16/05/17 M2207 - [email protected] 5/15 Code du client ECHO import java.io.*; import java.net.*; public class ClientEcho { public static void main(String args[]) { try { Socket s=new Socket("localhost",7); PrintStream sockOut=new PrintStream(s.getOutputStream()); InputStream is=s.getInputStream(); InputStreamReader isr=new InputStreamReader(is); BufferedReader sockIn=new BufferedReader(isr); sockOut.println("Hello"); //sockOut.flush(); // Force l'émission (non nécessaire ici) String recu=sockIn.readLine(); System.out.println("Rx : "+recu); s.close(); } catch(Exception e) {System.err.println(e);} } } 16/05/17 M2207 - [email protected] 6/15 Code du serveur ECHO import java.io.*; import java.net.*; public class ServeurEcho { public static void main(String args[]) { try { ServerSocket srv=new ServerSocket(7); Socket cli=srv.accept(); PrintStream sockOut=new PrintStream(cli.getOutputStream()); BufferedReader sockIn=new BufferedReader( new InputStreamReader(cli.getInputStream())); String message=sockIn.readLine(); System.out.println("Rx : "+message); sockOut.println(message); //sockOut.flush(); System.out.println("Tx : "+message); cli.close(); srv.close(); } catch(Exception e) {System.err.println(e);} } } 16/05/17 M2207 - [email protected] 7/15 Serveur ECHO Multi-Processus Un des gros inconvénients du code précédent réside dans le fait qu'un seul client peut être servi à la fois et qu'une fois cela fait, le serveur s'arrête ! Il faut donc faire une boucle infinie pour accepter les clients et créer un nouveau processus à chaque fois. Ce processus devra gérer les échanges particuliers avec le client. 16/05/17 M2207 - [email protected] 8/15 Code du serveur ECHO MP (1) import java.io.*; import java.net.*; public class ServeurEchoMP extends Thread { Socket client; ServeurEchoMP(Socket c) {client=c;} public static void main(String args[]) { try { ServerSocket srv=new ServerSocket(7); while(true) { Socket cli=srv.accept(); System.out.println("Connexion du client : "+cli); ServeurEchoMP s=new ServeurEchoMP(cli); s.start(); // Démarrage du processus : exécute run() !!! } } catch(Exception e) {System.err.println(e);} } 16/05/17 M2207 - [email protected] 9/15 Code du serveur ECHO MP (2) public void run() { try { PrintStream sockOut=new PrintStream(client.getOutputStream()); BufferedReader sockIn=new BufferedReader( new InputStreamReader(client.getInputStream())); String message=sockIn.readLine(); System.out.println("Rx : "+message); sockOut.println(message); //out.flush(); System.out.println("Tx : "+message); client.close(); } catch(Exception e) { System.err.println(e); } } } 16/05/17 M2207 - [email protected] 10/15 Envoi de données en UDP String msg="un message"; byte[] data=msg.getBytes(); InetAddress addr= InetAddress.getByName("localhost"); DatagramPacket packet= new DatagramPacket(data,data.length,addr,1234); DatagramSocket ds=new DatagramSocket(); ds.send(packet); ds.close(); 16/05/17 M2207 - [email protected] 11/15 Réception de données en UDP DatagramSocket ds=new DatagramSocket(1234); byte[] buffer=new byte[1024]; DatagramPacket packet= new DatagramPacket(buffer,buffer.length); ds.receive(packet); String msg=new String(packet.getData()); System.out.println("Message: "+msg); ds.close(); 16/05/17 M2207 - [email protected] 12/15 Envoi en Multicast String msg="un message"; byte[] data=msg.getBytes(); InetAddress addr= InetAddress.getByName("224.0.1.20"); DatagramPacket packet= new DatagramPacket(data,data.length,addr,1234); MulticastSocket ms=new MulticastSocket(); ms.send(packet); ms.close(); 16/05/17 M2207 - [email protected] 13/15 Réception en Multicast MulticastSocket s=new MulticastSocket(1234); InetAddress ip= InetAddress.getByName("224.0.1.20"); s.joinGroup(ip); byte[] buffer=new byte[1024]; DatagramPacket packet= new DatagramPacket(buffer,buffer.length); s.receive(packet); System.out.println("From : "+packet.getAddress()); System.out.println("Message : "+packet.getData()); s.leaveGroup(ip); s.close(); 16/05/17 M2207 - [email protected] 14/15 Références <javaDoc>/technotes/guides/net/index.html http://jcp.org/ 16/05/17 M2207 - [email protected] 15/15