Introduction à la programmation de clients/serveur TCP/IP en Java
Transcription
Introduction à la programmation de clients/serveur TCP/IP en Java
Introduction à la programmation de clients/serveur TCP/IP en Java Rushed Kanawati LIPN, CNRS UMR 7030 Université Paris 13 http://lipn.fr/∼kanawati [email protected] December 17, 2012 R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 1 / 34 Plan 1 Introduction 2 Classes Java pour la programmation réseaux: TCP/IP La classe InetAddress Classes pour communication UDP Serveur UDP multi-threads Communication Multicast Communication TCP R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 2 / 34 Introduction Objectifs Introduction à la programmation d’applications réseaux en Java. Programmation de clients/serveurs : UDP et TCP Programmation de clients/Serveur réseaux multi-threads Programmation d’applications distribuées avec java RMI: Remote Method Invocation R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 3 / 34 Introduction Rappel : Architecture Logicielle TCP/IP R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 4 / 34 Introduction Communication TCP/TP : Caractérisation Adresses IP source et destination Numéro de ports source et destination. Protocole de transport utilisé : UDP ou TCP R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 5 / 34 Introduction Numéro de Port Un port désigne le SAP (Service Access Point) de la couche application. L’adresse d’une application sur le réseau est donc définie par le couple : @IP d la machine : numéro de port. L’IANA1 répartit les numéros de ports en trois catégories : Les ports systèmes : 0 - 1023. Sous Linux l’utilisation de ces ports nécessite d’avoir les privilèges d’administrateur. Les ports déposés : 1024 - 49151 sont disponibles pour les utilisateurs et peuvent eux aussi être déposés auprès de l’ IANA Les ports privés : 49152 à 65535. 1 Internet Assigned Numbers Authority, http://www.iana.org R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 6 / 34 Introduction Le concept de socket Un socket est une interface entre une application et un service de la couche de transport. Plusieurs types de socket : socket UDP et socket TCP. Il est représenté comme un fichier : l’écriture dans ce fichier corresponds à l’envoie d’un message selon le protocole associé (UDP ou TCP). La réception d’un message se fait par une opération de lecture. Un socket est associé alors à un protocole de transport et à un numéro de port. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 7 / 34 Classes Java pour la programmation réseaux: TCP/IP TCP/IP : Programmation en Java Le paquetage java.net offre les classes de base : InetAddress : pour la manipulation d’adresses IP. DatagramSocket : pour la manipulation de sockets UDP. DatagramPacket : pour la manipulation de paquets UDP. ServerSocket : pour la manipulation de socket de serveurs TCP Socket : pour la manipulation de socket TCP d’échange de données. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 8 / 34 Classes Java pour la programmation réseaux: TCP/IP La classe InetAddress La classe InetAddress Cette classe n’offre pas de constructeurs. La création d’un objet passe par l’appel d’une des méthodes statiques suivantes : static InetAddress getLocalHost() throws UnknownHostException Retourne un objet InetAddress représentant la machine locale public static InetAddress getByName(String host) throws UnknownHostException Retourne un objet InetAddress qui corresponds ) la résolution par le système DNS de nom host. public static InetAddress[] getAllByName(String host) throws UnknownHostException Retourne toutes les adresses retrouvées de host. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 9 / 34 Classes Java pour la programmation réseaux: TCP/IP La classe InetAddress La classe InetAddress : Exemples InetAddress a ,b , c ; ... try { a = InetAddress . getLocalHost (); b = InetAddress . getByName ( " iutv . univ - paris13 . fr " ); c = InetAddress . getByName ( " 127.0.0.1 " ); } catch ( U n k n o w n H o s t E x c e p t i o n e ) { ... } R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 10 / 34 Classes Java pour la programmation réseaux: TCP/IP La classe InetAddress La classe InetAddress : méthodes de services public String getHostName() Retourne le nom complet correspondant à l’adresse IP public String getHostAddress() Retourne l’adresse IP sous forme numérique. public byte[] getAddress() Retourne l’adresse IP sous forme d’une suite d’octets. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 11 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP Rappel : Protocole UDP UDP opère en mode non connecté : échange de datagramms (paquets) L’entête d’un paquet UDP contient les numéros de ports source et destination. Les adresses IP sont dans l’entête IP encapsulé dans le paquet. Un paquet UDP contient donc : Les adresses IP source et destination, les ports source et destination et le message à envoyer (suite d’octets) R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 12 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP La classe DatagramPacket Classe de manipulation de paquets UDP. Constructeur pour encapsuler un paquet UDP à recevoir : DatagramPacket(byte[] buf, int length) où buf est le message à recevoir et length la taille du message. Constructeur pour encapsuler un paquet UDP à envoyer : DatagramPacket(byte[] buf, int length, InetAddress address, int port) où buf est le message à envoyer, length la taille du message, address est l’adresse IP destination et port est le port destination. Attention le message buf doit être initialisé avant la construction du paquet. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 13 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP La classe DatagramPacket : méthodes de services InetAddress getAddress() Retourne l’adresse IP de la machine distante. int getPort() Retourne le numéro de port distant. byte[] getData() Retourne la partie donnée du paquet. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 14 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP Classe DatagramSocket Constructeurs : public DatagramSocket() throws SocketException Création d’un socket UDP associé à un port libre (privé) public DatagramSocket(int port) throws SocketException Création d’un socket UDP associé au port port R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 15 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP DatagramSocket : Méthodes de service public void send(DatagramPacket p) throws IOException Envoyer le paquet p public void receive(DatagramPacket p) throws IOException recevoir un paquet p. L’appel ce cette méthode est bloquante. public void setSoTimeout(int timeout) throws SocketException Permet de débloquer le thread exécutant une méthode recieve au bout de timeout seconds. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 16 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP Exemple : Envoie de message UDP (1) /* Initialisation d ’ un socket UDP */ DatagramSocket socket = new DatgramSocket () /* identification de l ’ application destination : @IP ; por InetAddress address = InetAddress . getByName ( " iutv . univ - paris13 . fr " ); int port = 8888; /* Le message à envoyer */ String s = new String ( " Bonjour Paris 13 " ); byte [] message = new byte [1024]; /* transformation du message en suite d ’ octets */ message = s . getBytes (); R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 17 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP Exemple : Envoie de message UDP (2) /* Formation du paquet UDP à envoyer */ DatagramPacket paquet = new DatagramPacket ( message , longueur , address , port ); /* envoi du paquet */ socket . send ( paquet ); R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 18 / 34 Classes Java pour la programmation réseaux: TCP/IP Classes pour communication UDP Exemple : Réception de message UDP (1) try { DatagramSocket socket = new DatagramSocket (8888); byte [] buffer = new byte [1024]; // On associe un paquet à un buffer vide pour la réception DatagramPacket paquet = new DatagramPacket ( buffer , buffer . length ); /* attente de réception */ socket . receive ( paquet ); /* affichage du paquet reçu */ String s = new String ( buffer ); System . out . println ( " message reçu : " + s ); } catch ( Exception e ) {} R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 19 / 34 Classes Java pour la programmation réseaux: TCP/IP Serveur UDP multi-threads Serveur UDP multi-threads Pourquoi ? Réduire le temps d’attente de traitement de requêtes en permettant le traitement parallèle. Comment ? Pour chaque paquet UDP reçu par le serveur, un thread de traitement se charge du traitement du paquet. Optimisation : Un serveur peut anticiper la création de threads de traitement afin de réduire le temps d’attente de traitement d’une requête. R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 20 / 34 Classes Java pour la programmation réseaux: TCP/IP Serveur UDP multi-threads Serveur UDP multi-threads : Exemple DatagramSocket socket = new DatagramSocket (8888); while ( true ) { byte [] buffer = new byte [1024]; DatagramPacket paquet = newDatagr amPack et ( buffer , buffer . length ); socket . receive ( paquet ); /* Lancement d ’ un thread de traitement à la réception d ’ un paquet */ new Handler ( paquet ). start (); /* se mettre à nouveau à attendre d ’ autres requ^ e tes */ } R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 21 / 34 Classes Java pour la programmation réseaux: TCP/IP Serveur UDP multi-threads Serveur UDP multi-threads : Exemple class Handler extends Thread { private DatagramPacket p ; public Handler ( DatagramPacket p ) throws Exception { if ( p != null } { this . p = p ; } else { throw new Exception (); } public void run () { /* traitement du paquet */ } R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 22 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication Multicast Communication Multicast Communication Multicast : Diffusion restreinte de messages au sein d’un groupe. Un groupe multicarte est identifié par une adresse IP de classe D. Plage d’adresses de classe D (IPv4) : 224.0.0.1 - 239.255.255.255. 224.0.0.0 - 224.0.0.255 : adresses réservées pour des services systèmes. 224.0.0 - 238.255.255.255 : adresses publiques 239.0.0.0 - 239.255.255.255 : adresses privées. Utilisation d’un socket spécial : MulticastSocket R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 23 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication Multicast La classe MulticastSocket Sous-classe de DatagramSocket Constructeurs : public MulticastSocket () throws IOException /* Création d ’ un socket multicast associé à un port UDP libre */ public MulticastSocket ( int port ) throws IOException /* Création d ’ un socket multicast associé au port UDP port */ R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 24 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication Multicast La classe MulticastSocket Quelques méthodes de services : public void joinGroup ( InetAddress mcastaddr ) throws IOException /* rejoindre un groupe de multicast */ public void leaveGroup ( InetAddress mcastaddr ) throws IOException /* Quitter un groupe de multicast */ public void setTimeToLive ( int ttl ) throws IOException /* Fixer le TTL associé aux paquets UDP */ public int getTimeToLive () throws IOException R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 25 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication Multicast Multicast : exemple public class Multicast { public static void main ( String [] args ){ MulticastSocket soc ; InetAddress adr ; DatagramPacket p ; byte [] msg ; try { adr = InetAddress . getByName ( " 228.5.6.7 " ); soc = new MulticastSocket (); soc . joinGroup ( adr ); msg = new String ( " Salut !! " ). getBytes (); p = new DatagramPacket ( msg , msg . length , adr , 8888); soc . send ( p ); } catch ( Exception ex ){} } R. Kanawati (LIPN) Programmation réseau en java } December 17, 2012 26 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication Multicast Multicast : exemple public class MCClient { public static void main ( String [] args ){ MulticastSocket soc ; InetAddress adr ; DatagramPacket p ; byte [] msg ; try { adr = InetAddress . getByName ( " 228.5.6.7 " ); soc = new MulticastSocket (8888); soc . joinGroup ( adr ); msg = new byte [1024]; p = new DatagramPacket ( msg , msg . length ); soc . receive ( p ); System . out . println ( " Message reçu " + new String ( p . getData ())); } catch ( Exception ex ){} }} R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 27 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP Communication TCP Communication en mode connecté Communication en trois phases : connexion, échange, déconnexion. Contrôle d’erreurs et de perte de messages : mécanismes d’acquittements. La phase de connexion est asymétrique. On parle alors de serveur et de client. Le serveur TCP utilise un socket de la classe ServerSocket. L’échange de messages se fait à travers de sockets de la classe Socket R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 28 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP La classe ServerSocket Rôle : attendre la réception de demande de connexion. Puis création d’un socket d’échange sur acceptation. Constructeur : public ServerSocket ( int port ) throws IOException ; /* Création d ’ un socket de connexion TCP associé au port port */ Métode d’acceptation de demande de connexion: public Socket accept () throws IOException ; /* Attente de demande de connexion , création s ’ un socket d ’ échange après acceptation */ l’appel de la méthode accept() est bloquant R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 29 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP La classe Socket Constructeur : public Socket ( InetAddress server , int port ) throws IOException ; /* Demande de connexion au serveur TCP dont l ’ adresse est server et qui est à l ’ écoute sur port */ Méthode d’échange de données : public InputStream getInputStream (); /* renvoyer un flus d ’ entrée pour lire les messages * public OutputStream getOutputStream (); /* renvoyer un flus d ’ entrée pour l ’ envoi de messages */ R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 30 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP Serveur TCP : exemple public class EchoServer { public static void main ( String [] args ) { ServerSocket serSoc ; DataInputStream in ; PrintStream out ; Socket soc ; try { serSoc = new ServerSocket ( Integer . parseInt ( args [0])); while ( true ) { soc = serSoc . accept (); in = new DataInputStream ( soc . getInputStream ()); out = new PrintStream ( soc . getOutputStream ()); R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 31 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP Serveur TCP : exemple while ( true ) { String ligne = in . readLine (); out . println ( " ECHO : " + ligne ); } } } catch ( Exception e ) { } } } R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 32 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP Client TCP : exemple public class EchoClient { public static void main ( String [] args ) { Socket soc ; DataInputStream in ; DataInputStream userInput ; PrintStream out ; String ligne ; try soc in = out { = new Socket ( args [0] , Integer . parseInt ( args [1])); new DataInputStream ( soc . getInputStream ()); = new PrintStream ( soc . getOutputStream ()); userInput = new DataInputStream ( System . in ); R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 33 / 34 Classes Java pour la programmation réseaux: TCP/IP Communication TCP Client TCP : exemple while ( true ) { ligne = userInput . readLine (); if ( ligne . equals ( " . " )) break ; out . println ( lingo ); System . out . println ( in . readLine ()); } } catch ( Un k n o w n H o s t E x c e p t i o n e ) { } catch ( IOException e ) { } } } R. Kanawati (LIPN) Programmation réseau en java December 17, 2012 34 / 34