Programmation Réseaux Illustration : Les Sockets en Java

Slides:



Advertisements
Présentations similaires
Sérialisation des objets
Advertisements

Le mécanisme des exceptions
Cours réseaux Essi2 Anne-Marie Déry
SI3 MAM3 Hydro Nathan Cohen Igor Litovsky Christophe Papazian
Plan de l’enseignement
ESSI AM Dery Merci à Rémi Vankeisbelck, Michel Riveill etc
Retour sur RMI.
Programmation Réseaux Illustration : Les Sockets en Java
1 Plan de lenseignement Cours Introduction au réseau via les objets distants (Application à RMI) Ce que cache RMI : programmation socket – mode connecté
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Java et la réflexivité.
Communication par diffusion : Multicast
Java et la réflexivité. Java reflection is useful because it supports dynamic retrieval of information about classes and data structures by name, and.
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Des sockets à RMI Programmation réseau versus programmation objet
Applications distribuées et parallèlisme La communication ne doit pas rester bloquée pour un client.
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Programmation Réseaux Illustration : Les Sockets en Java
ESSI AM Dery Merci à Rémi Vankeisbelck, Michel Riveill etc
Communication par diffusion : Multicast Clientn Serveur Client1 Client2 Gr.
ESSI AM Dery Merci à Rémi Vankeisbelck, Michel Riveill etc
Les Sockets et Java Cours Harmonisation Anne-Marie Déry.
Java et la réflexivité. Java reflection is useful because it supports dynamic retrieval of information about classes and data structures by name, and.
Des sockets à RMI. Pourquoi ? Maturation de la technologie orientée objet –ADA, Modula –Smalltalk, C++, Java Maturation des communications Client- Serveur.
Des sockets à RMI.
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
Introduction aux applications réparties
Plan du cours La sérialisation: – comment stocker et restaurer les Objets? Les interfaces graphiques et la programmation évènementielle. –Comment concevoir.
Cours 6 : XML et les architectures N-tiers – Tier Applicatif

À travailler seuls Concepts généraux Mise en œuvre Java Année
Common Gateway Interface
Programmation orientée objet
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
COURS DE PROGRAMMATION ORIENTEE OBJET :
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Analyse des protocoles de la couche application
Labview Programmation réseau Communication par sockets
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
Système d’Exploitation
Les relations clients - serveurs
FICHIERS : Définition : Algorithme général:
À travailler seuls Concepts généraux Mise en œuvre Java Année
Programmation concurrente
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
COURS DE PROGRAMMATION ORIENTEE OBJET :
1212 Entrée et sortie de fichiers Objectifs À la fin de ce cours, vous serez capables de : • Lire à partir de la console • Écrire sur la console.
Présentation de CORBA et de IIOP
Développement d’application client/serveur
Créer des packages.
Cours Les flux ou streams. Cours 162 Flux : objet possédant des méthodes capables de lire ou écrire des flots d’octets sur tout support (mémoire,
CEG3585/CEG3555 Tutorat 2 Hi ver 2013.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
Les Réseaux Informatiques Clients & Serveurs Le protocole FTP Laurent JEANPIERRE DEUST AMMILoR.
Les sockets.
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
Schéma de conception Factory Method Exemple Sylvain Giroux.
Les RPC remote procedure call
 Formulaires HTML : traiter les entrées utilisateur
Ingénierie des réseaux - Chapitre 2 bis Les sockets en Java
Programmation Réseaux Qu’avez-vous retenu ? Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java.
Architecture Client/Serveur
L. Gurret – M. Herve – P. Mignon – J. Prarioz. Introduction  Dernière étape d’analyse  Cahier des charges, spécifications et conception orientée objet.
Java Remote Method Invocation
Client/Server Socket. Client/Serveur.
Transcription de la présentation:

Programmation Réseaux Illustration : Les Sockets en Java Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java

Réseau et département SI Couches Réseaux : protocoles TCP – UDP Programmation Réseaux Sockets Java et C Introduction aux applications réparties Programmation par Composants Expériences Industrielles Administration et sécurité des réseaux Réseaux sans fil Applications Temps Réel SI 4 AL IAM et SSR

Questions préliminaires Différences entre les protocoles de transport TCP et UDP ? Utilisation des adresses Internet ? Utilisation des ports ? Programmation sockets : avantages et inconvénients Client : ? Serveur : ? Serveur de noms ? (DNS, LDAP) ?

Architecture client serveur Mode de communication qu’un hôte établit avec un autre hôte qui fournit un service quelconque Serveur Client opération send request application send reply « protocole d’application » marshalling 

Comment cela fonctionne au niveau du réseau Identification de la machine qui abrite le serveur par le client Identification du serveur sur la machine Canal de communication entre le serveur et le client Construction de la trame réseau Echange du protocole d’application

Sockets Outil de communication pour échanger des données entre un client et un serveur Canaux de communication (descripteur d’entrée sortie dans lesquels on écrit et sur lesquels on lit) Gestion similaire des entrées sorties standard (écran, clavier) et des fichiers

Un socket : une entrée sortie dédiée au réseau Gestion similaire des entrées sorties standard (écran, clavier) et des fichiers En sortie (ex. System.out) : java.io.PrintStream (ou PrintWriter) utilise un flot dirigé vers une sortie java.io.OutputStream En entrée (ex. System.in) : java.io.InputStream (ou BufferedReader)

Plus précisément un socket Plusieurs types de sockets : pour la communication par flot de données - fortement connectée - synchrone - type client-serveur pour communication réseau par message - en mode datagramme - en mode déconnecté pour communication réseau par diffusion

Exemples d’applications Un serveur d’Echo Un exemple : le service SMTP Demande de citations Diffusion de citations

Sockets en Java ? BSD sockets UNIX au dessus de TCP ou UDP Une infrastructure puissante et flexible pour la programmation réseau En Java toutes les classes relatives aux sockets sont dans le package java.net

Le Package net Des Exceptions Des entrées Sorties Des Sockets …... Plusieurs hiérarchies de classes

Des types de Sockets Object ServerSocket DatagramSocket MulticastSocket Socket

Des exceptions Exception IOException SocketException ProtocolException UnknownHostException UnknownServiceException BindException ConnectException

Des Entrées Sorties Object OutputStream InputStream FileOutputStream FileInputStream ObjectInputStream FilterInputStream DataInputStream FilterOutputStream DataOutputStream

Autres Classes Object InetAdress DatagramPacket SocketImpl PlainSocketImpl

Java.net.InetAddress : nommage La classe InetAddress 2 constructeurs : un par défaut qui crée une adresse vide (cf la méthode accept sur Socket) un qui prend le nom de la machine hôte et l’adresse IP de la machine. Des accesseurs en lecture : pour récupérer l’adresse IP d’une machine (getByName, getAllByName), des informations sur la machine hôte (getLocalHost, getLocalAddress, getLocaName) Des comparateurs : égalité (equals) et type d’adresse (isMulticastAddress) …..

Communication Client Serveur traditionnelle Fortement connectée TCP

Flot de requêtes du client vers le serveur TCP fournit un transfert fiable, conservant l’ordre de transfert des octets (“pipe”) entre le client et le serveur Point de vue application Serveur Client opération Ouvrir connexion req1 application req2 req3 reqn Fermer la connexion

Interaction Client/server : socket TCP wait for incoming connection request connectionSocket = welcomeSocket.accept() create socket, port=x, for incoming request: welcomeSocket = ServerSocket() connect to hostid, port=x clientSocket = Socket() close connectionSocket read reply from clientSocket send request using read request from write reply to TCP connection setup Serveur (s’exécutant sur l’hôte) Client

Scénario d’un serveur pour un client Créer le socket de communication avec le client Attente de données sur le flux d’entrée Réception et Analyse des données en entrée Calcul Construction de la réponse Ecriture sur le flux de sortie Fermer le socket de communication

Scénario d’un client Créer le socket de connexion avec le serveur Attendre que la connexion soit établie Récupérer la socket de communication Préparer la requête l’envoyer sur le flux de sortie Attendre des données sur le flux d’ entrée les lire et les traiter Fermer le socket

TCP et Sockets 2 classes : Socket et ServerSocket (java.net package) pour les canaux de communication Classes pour le flot de données XInputStream et XOutputStream

Connexion + « Marshalling » Transfert de données Connexion + « Marshalling »

Accepter les connexions Dans un serveur ? Créer un objet socket pour écouter les demandes de connexion sur le numéro de port associé au service Créer un objet socket pour accepter une connexion d ’un client cet objet servira pour tous les transferts d ’information de ce client vers le serveur

Dans un serveur ? Accepter les connexions ServerSocket myService; try { myService = new ServerSocket(PortNumber); } catch (IOException e) {System.err.println(e);} Création d’un objet socket pour écouter et accepter les connexions des clients Socket clientSocket = null; try {clientSocket = myService.accept();} catch (IOException e) {System.err.println(e); }

Demander à se Connecter = ouvrir un socket Dans un client identifier la machine à laquelle on veut se connecter et le numéro de port sur lequel tourne le serveur implique de créer un socket pour cette communication

Se connecter Comment ouvrir un socket ? Dans un client Socket myClient; try { myClient = new Socket("Machine name", PortNumber); } catch (IOException e) { System.out.println(e); Machine name : machine à laquelle on veut se connecter PortNumber port sur lequel tourne le serveur (> 1023)

Comment envoyer une information ? Côté client : pour envoyer une requête au serveur Côté serveur : pour envoyer une réponse au client 1 Créer un flux de sortie pour le socket pour écrire l’information 2 Constituer le contenu des données à émettre (transformer entiers, doubles, caractères, objets en lignes de texte)

Côté Serveur Pour envoyer des informations au client Exemple d’entrée sortie DataOutputStream : écrire des types de données primitifs; output= new DataOutputStream(clientSocket.getOutputStream());

Côté Client Côté client : pour envoyer une information au serveur Autre exemple d’entrée sortie PrintStream pour afficher des valeurs des types de base (write et println) PrintStream output; try {output = new PrintStream(myClient.getOutputStream();} catch (IOException e) {System.err.println(e);} …..

Comment recevoir de l ’information ? Côté serveur : on doit lire la requête du client Côté client : on doit recevoir une réponse du serveur 1 Créer un flux d ’entrée pour le socket et lire l ’information sur le flux 2 Reconstituer les données émises ( entiers, doubles, caractères, objets) à partir des lignes de texte reçues

Côté Serveur pour recevoir les données d’un client DataInputStream input; try { input = new DataInputStream(clientSocket.getInputStream()); } catch (IOException e) {System.out.println(e);}

Côté Client Côté client : pour recevoir une réponse du serveur DataInputStream : lire des lignes de texte, des entiers, des doubles,des caractères... ( read, readChar, readInt, readDouble, and readLine,. ) (writeBytes…) try {input = new DataInputStream(myClient.getInputStream());} catch (IOException e) {System.out.println(e);}

Autres entrées sorties echoSocket = new Socket( "jessica", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream())); ATTENTION Le BufferedReader prend un Reader en paramètre et non un Stream Utilisation des ObjectInputStream et ObjectOutputStream L’output doit être initialisé en premier sinon blocage à la Création du flux de sortie.

Entrées sorties : comment procéder ? Quid du marshalling ? l’information qui est lue doit être du même type et du même format que celle qui est écrite ATTENTION au choix de vos entrées sorties – respecter la Cohérence des données transmises Le client doit il connaître la nature des E/S du serveur pour être écrit ?

Comment se déconnecter ? Fermer correctement les flux d’entrée sortie et les sockets en cause. Côté client Côté serveur

Comment fermer un socket ? Fermer les output et input stream avant le socket. Côté client output.close(); input.close(); myClient.close(); Côté serveur clientSocket.close(); myService.close();

Sockets (Communication Client serveur) Le serveur est à l’écoute des requêtes sur un port particulier Un client doit connaître l’hôte et le port sur lequel le serveur écoute. Le client peut tenter une connexion au serveur Le serveur connecte le client sur un nouveau no de port et reste en attente sur le port original Client et serveur communiquent en écrivant et lisant sur un socket

Serveur Echo Un serveur similaire à echo ( port 7). Reçoit un texte du client et le renvoie identique Le serveur gère un seul client.

Déclarations import java.io.*; import java.net.*; public class echo3 { public static void main(String args[]) { ServerSocket echoServer = null; String line; DataInputStream is; PrintStream os; Socket clientSocket = null; try { echoServer = new ServerSocket(9999);} catch (IOException e) {System.out.println(e); }

try { clientSocket = echoServer.accept(); is = new DataInputStream(clientSocket.getInputStream()); os = new PrintStream(clientSocket.getOutputStream()); while (true) { line = is.readLine(); os.println(line); } catch (IOException e) { System.out.println(e);} } }

Comment écrire un client ? Toujours 4 étapes Ouvrir un socket. Ouvrir un input et un output stream sur le socket. Lire et écrire sur le socket en fonction du protocole du serveur. Effacer Fermer Seule l’étape 3 change selon le serveur visé

Client SMTP (Simple Mail Transfer Protocol), import java.io.*; import java.net.*; public class smtpClient { public static void main(String[] args) { Socket smtpSocket = null; // le socket client DataOutputStream os = null; // output stream DataInputStream is = null; // input stream try { smtpSocket = new Socket("hostname", 25); os = new DataOutputStream(smtpSocket.getOutputStream()); is = new DataInputStream(smtpSocket.getInputStream()); } catch (UnknownHostException e) { System.err.println("Don't know about host: hostname"); } catch (IOException e) { System.err.println("Couldn't get I/O for the connection to: hostname"); }

Le protocole SMTP, RFC1822/3 if (smtpSocket != null && os != null && is != null) { try{os.writeBytes("HELO\n"); os.writeBytes("MAIL From: <pinna@essi.fr>\n"); os.writeBytes("RCPT To: <pinna@essi.fr>\n"); os.writeBytes("DATA\n"); os.writeBytes("From: pinna@essi.fr\n"); os.writeBytes("Subject: Qui est là ?\n"); os.writeBytes("Vous suivez toujours ?\n"); // message os.writeBytes("\n.\n"); os.writeBytes("QUIT");

SMTP // attente de "Ok" du serveur SMTP, . String responseLine; while ((responseLine = is.readLine()) != null) { System.out.println("Server: " + responseLine); if (responseLine.indexOf("Ok") != -1) {break;}} os.close(); is.close(); smtpSocket.close(); } catch (UnknownHostException e) { System.err.println("Trying to connect to unknown host: " + e); } catch (IOException){ System.err.println("IOException: " + e);} } } } .

TCP et Sockets La classe ServerSocket des constructeurs : par défaut, no de port associé, + taille de la liste de clients en attente + adresse... des accesseurs en lecture : no de port sur lequel le socket écoute, adresse à laquelle il est connecté (getPort, getInetAddress, …) des méthodes : accept pour accepter une communication avec un client, close ...

TCP et Sockets La classe Socket : une batterie de constructeurs : par défaut, no de port + adresse / nom de machine et service distante, + no de port + adresse locale, créent un socket en mode Stream ou DataGramme des accesseurs en lecture : no de port et adresse à laquelle il est connecté, no de port et adresse à laquelle il est lié, input et output Stream associés (getPort, getInetAddress, getLocalPort, getLocalAddress, getInputStream, getOutputStream…) des méthodes : close ...

Applications distribuées et parallèlisme La communication ne doit pas rester bloquée pour un client

Interaction Client/server : socket TCP wait for incoming connection request connectionSocket = welcomeSocket.accept() create socket, port=x, for incoming request: welcomeSocket = ServerSocket() connect to hostid, port=x clientSocket = Socket() close connectionSocket read reply from clientSocket send request using read request from write reply to TCP connection setup Serveur (s’exécutant sur l’hôte) Client

Plusieurs Clients Utiliser des threads pour accepter plusieurs clients simultanément. Le serveur gère un thread par client

Plusieurs clients application S1 application S2 Clientn Sn application Serveur Client1 Ouvrir connexion application S1 Client2 application S2 Clientn Sn application

Quelques mots sur les Threads Un thread permet l’exécution d’un programme. Une application peut avoir de multiples threads qui s ’exécutent concurremment (Chaque thread a une priorité). Chaque thread a un nom. Plusieurs threads peuvent avoir le même. Le nom est généré si non spécifié. Il y a 2 façons de créer un nouveau thread d’exécution. déclarer une sous classe de Thread et surcharger la méthode run. Une instance de la sous classe peut alors être allouée et démarrer. déclarer une classe qui implémente Runnable et donc la méthode run. Une instance de la classe peut être allouée, passée comme argument à la création d’un thread et démarrée.

Scénario du Serveur Multithreadé while (true) { accept a connection ; create a thread to deal with the client ; end while

public class MultiServerThread extends Thread { private Socket socket = null; public MultiServerThread(Socket socket) { super("MultiServerThread"); this.socket = socket; } public void run() { try { PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); …… } out.close(); in.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }

public class MultiServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true; try { serverSocket = new ServerSocket(4444); } catch (IOException e) { System.err.println("Could not listen on port: 4444."); System.exit(-1); } while (listening) new MultiServerThread(serverSocket.accept()).start(); serverSocket.close(); } }

Programmation Réseaux Illustration : Les Sockets en Java PARTIE 2 Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java

Besoins d’une application Client-Serveur Similitudes avec un appel téléphonique via un standard 1. Trouver l’adresse du serveur : trouver le no de téléphone de l’entreprise 2. Demander un service spécifique : s’adresser à un service ou une personne précise de l’entreprise (no de poste) 3. Faire la requête 4. Obtenir une réponse Adresse d’un serveur ? Identification d’un service ?

Un peu de vocabulaire Client : entité qui fait l ’appel Sockets : moyen de communication entre ordinateurs Adresses IP : adresse d’un ordinateur Serveur : entité qui prend en charge la requête Serveur de noms (DNS, LDAP) : correspondances entre noms logiques et adresses IP (Annuaire) Port : canal dédié à un service Protocole : langage utilisé par 2 ordinateurs pour communiquer entre eux

Adresse Internet et Port attribuée à chaque nœud du réseau série d ’octets dont la valeur dépend du type de réseau associée à un nom logique (Domain Name Server) Chaque hôte possède environ 65535 ports Port canal dédié à un service spécifique 80 pour le service http 25 pour le service SMTP TCP implique une file d’attente par connexion UDP implique une file d’attente unique pour le port

Exemples d ’adresses Internet 157.169.9.15 oscar.essi.fr oscar 157.169.20.5 accueil.essi.fr accueil 157.169.20.4 compta.essi.fr compta 157.169.25.201 www-local.essi.fr www-local 157.169.10.222 pcprofs.essi.fr pcprofs 157.169.4.50 ada.essi.fr ada 157.169.10.120 macserver.essi.fr macserver 157.169.10.240 demo.essi.fr demo 157.169.1.20 bibli.essi.fr bibli 157.169.25.110 sfe-srv.essi.fr sfe-srv sfe 157.169.1.153 bde.essi.fr bde 157.169.3.204 niv1a.essi.fr niv1a 157.169.1.155 dessi.essi.fr dessi 157.169.10.2 jessica.essi.fr jessica print2 ypcat hosts sous linux

Exemples d ’adresses Essi : 157.169 I3S: 134.59 serveurs : 25 157.169.25.200 news-srv.essi.fr news-srv www.essi.fr www-srv.essi.fr news 134.59.132.21 dolphin.unice.fr 157.169.10.1 essi2.essi.fr loghost essi2 Essi : 157.169 I3S: 134.59 serveurs : 25 Administration : 1 …….

Ports réservés 1 à 1024 services fondamentaux (administrateurs) (sous unix cf. le fichier /etc/services, ypcat services) 1025 à 5000 disponibles pour les utilisateurs TCP Serveur FTP : 21 Serveur Telnet : 23 Serveur SMTP : 25 UDP Agent SNMP : 161 Logger SNMP : 162 …. Serveur multi processus Applications transactionnelles

Programmation Socket Comment construire des applications client/server qui communiquent via les sockets Une porte à travers laquelle l’application peut à la fois envoyer et recevoir des messages d’une autre application socket Deux types de transports via les socket API: Datagramme (non reliable) Orienté flux d’octets (reliable)

Programmation socket avec TCP Lorsque le client crée le socket: le client TCP établit une connexion avec le serveur TCP Lorsque le client le contacte le serveur TCP crée une nouvelle socket pour que le processus serveur communique avec le client Permet de parler avec plusieurs clients Le Client doit contacter le serveur Le processus serveur doit être en train de s’exécuter Le serveur doit avoir créé un socket qui devient le point d’entrée des clients Le Client contacte le serveur en Créant un socket TCP client-localement Spécifiant l’adresse et le no de port number du processus serveur

Applications distribuées et parallèlisme La communication ne doit pas rester bloquée pour un client

Interaction Client/server : socket TCP wait for incoming connection request connectionSocket = welcomeSocket.accept() create socket, port=x, for incoming request: welcomeSocket = ServerSocket() connect to hostid, port=x clientSocket = Socket() close connectionSocket read reply from clientSocket send request using read request from write reply to TCP connection setup Serveur (s’exécutant sur l’hôte) Client

Plusieurs Clients Utiliser des threads pour accepter plusieurs clients simultanément. Le serveur gère un thread par client

Plusieurs clients application S1 application S2 Clientn Sn application Serveur Client1 Ouvrir connexion application S1 Client2 application S2 Clientn Sn application

Quelques mots sur les Threads Un thread permet l’exécution d’un programme. Une application peut avoir de multiples threads qui s ’exécutent concurremment (Chaque thread a une priorité). Chaque thread a un nom. Plusieurs threads peuvent avoir le même. Le nom est généré si non spécifié. Il y a 2 façons de créer un nouveau thread d’exécution. déclarer une sous classe de Thread et surcharger la méthode run. Une instance de la sous classe peut alors être allouée et démarrer. déclarer une classe qui implémente Runnable et donc la méthode run. Une instance de la classe peut être allouée, passée comme argument à la création d’un thread et démarrée.

Scénario du Serveur Multithreadé while (true) { accept a connection ; create a thread to deal with the client ; end while

public class MultiServerThread extends Thread { private Socket socket = null; public MultiServerThread(Socket socket) { super("MultiServerThread"); this.socket = socket; } public void run() { try { PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); …… } out.close(); in.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }

public class MultiServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true; try { serverSocket = new ServerSocket(4444); } catch (IOException e) { System.err.println("Could not listen on port: 4444."); System.exit(-1); } while (listening) new MultiServerThread(serverSocket.accept()).start(); serverSocket.close(); } }

Ce que RMI ne sait pas vraiment faire ? Communication asynchrone par messages Communication par diffusion

Communication par message : Envoi de datagrammes Serveur Client opération req1 application rep1 reqn repn

Programmation Socket avec UDP UDP: pas de “connexion” entre le client et le serveur Pas de lien privilégié entre le client et le serveur L’emetteur attache l’adresse IP et le port pour le retour. Le serveur doit extraire l’adresse IP et le port de l’expéditeur à partir du datagramme reçu application viewpoint UDP fournit un transfert non fiable de groupes d’octets (“datagrammes”) entre un client et le serveur UDP: les données transmises peuvent être reçues dans le désordre ou perdues

Client/server socket interaction: UDP create socket, clientSocket = DatagramSocket() Create, address (hostid, port=x, send datagram request using clientSocket create socket, port=x, for incoming request: serverSocket = DatagramSocket() read request from serverSocket close clientSocket read reply from clientSocket write reply to serverSocket specifying client host address, port umber Serveur Client

Scénario d’un serveur Créer le socket d ’entrée Création d ’un paquet d ’entrée Attente de données en entrée Réception et Analyse des données en entrée Calcul Création d’un paquet de sortie Préparation et Envoi de la réponse Fermer le socket d ’entrée

Scénario d’un client Créer le socket d ’entrée Créer un paquet de sortie Préparer et Envoyer une requête Créer un paquet d’entrée Attendre des données en entrée les recevoir et les traiter Fermer le socket d ’entrée

Datagrammes UDP et Sockets Datagramme = un message indépendant envoyé sur le réseau arrivée, temps d’arrivée et contenu non garantis 2 classes : DatagramPacket et DatagramSocket packages d’implémentation de communication via UDP de datagrammes

Exemple Un serveur de citation qui écoute un socket type datagram et envoie une citation si le client le demande Un client qui fait simplement des requêtes au serveur ATTENTION Plusieurs firewalls et routeurs sont configurés pour interdire le passage de paquets UDP

Une Application Client Serveur Le serveur reçoit en continu des paquets mode datagramme sur un socket un paquet reçu = une demande de citation d’un client le serveur envoie en réponse un paquet qui contient une ligne "quote of the moment" L’application cliente envoie simplement un paquet datagramme au serveur indiquant qu’il souhaite recevoir une citation et attend en réponse un paquet du serveur.

La classe QuoteServer socket = new DatagramSocket(4445); Création d’un DatagramSocket sur le port 4445 qui permet au serveur de communiquer avec tous ces clients try { in = new BufferedReader(new FileReader("one-liners.txt")); } catch (FileNotFoundException e) System.err.println("Couldn't open quote file. " + "Serving time instead."); } Le constructeur ouvre aussi un BufferedReader sur un fichier qui contient une liste de citations ( une citation par ligne)

suite contient une boucle qui tant qu’il y a des citations dans le fichier attend l’arrivée d ’un DatagramPacket correspondant à une requête client sur un DatagramSocket. Byte[] buf = new byte[256]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); En réponse une citation est mise dans un DatagramPacket et envoyée sur le DatagramSocket au client demandeur. String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes(); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet);

Suite Adresse Internet + numéro de port (issus du DatagramPacket ) = identification du client pour que le serveur puisse lui répondre L’arrivée du DatagramPacket implique une requête ->contenu du buffer inutile Le constructeur utilisé pour le DatagramPacket : un tableau d’octets contenant le message et la taille du tableau + L’adresse Internet et un no de port. Lorsque le serveur a lu toutes les citations on ferme le socket de communication. socket.close();

La classe QuoteClient envoie une requête au QuoteServer, attend la réponse et affiche la réponse à l’écran. Variables utilisées : int port; InetAddress address; DatagramSocket socket = null; DatagramPacket packet; byte[] sendBuf = new byte[256]; Le client a besoin pour s ’exécuter du nom de la machine sur laquelle tourne le serveur if (args.length != 1) { System.out.println("Usage: java QuoteClient <hostname>"); return; }

La partie principale du main Création d ’un DatagramSocket DatagramSocket socket = new DatagramSocket(); Le constructeur lie le Socket à un port local libre Le programme envoie une requête au serveur byte[] buf = new byte[256]; InetAddress address = InetAddress.getByName(args[0]); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); Ensuite le client récupère une réponse et l’affiche

Classe DatagramSocket Des constructeurs : par défaut, + no port + Adresse Inet Des accesseurs en lecture : adresse à laquelle le socket est lié, est connecté, le no port auquel il est lié, connecté, taille du buffer reçu ou envoyé (getInetAddress, getLocalAddress, getPort, getLocalPort, getReceivedBufferSize, getSendBufferSize…) Des méthodes : pour se connecter à une adresse, pour se déconnecter, pour envoyer un paquet datagramme, pour un recevoir un paquet datagramme (connect, disconnect, send, receive)

Classe DatagramPacket Des constructeurs : buffer + longueur de buffer + adresse destination + port… Des accesseurs en lecture : adresse à laquelle le paquet est envoyé, le no port à laquelle le paquet est envoyé, la donnée transmise (getAddress, getPort, getData, getLength…)

Communication asynchrone par messages Communication par diffusion

Communication par message : Envoi de datagrammes Serveur Client opération req1 application rep1 reqn repn

Programmation Socket avec UDP UDP: pas de “connexion” entre le client et le serveur Pas de lien privilégié entre le client et le serveur L’emetteur attache l’adresse IP et le port pour le retour. Le serveur doit extraire l’adresse IP et le port de l’expéditeur à partir du datagramme reçu application viewpoint UDP fournit un transfert non fiable de groupes d’octets (“datagrammes”) entre un client et le serveur UDP: les données transmises peuvent être reçues dans le désordre ou perdues

Client/server socket interaction: UDP create socket, clientSocket = DatagramSocket() Create, address (hostid, port=x, send datagram request using clientSocket create socket, port=x, for incoming request: serverSocket = DatagramSocket() read request from serverSocket close clientSocket read reply from clientSocket write reply to serverSocket specifying client host address, port umber Serveur Client

Scénario d’un serveur Créer le socket d ’entrée Création d ’un paquet d ’entrée Attente de données en entrée Réception et Analyse des données en entrée Calcul Création d’un paquet de sortie Préparation et Envoi de la réponse Fermer le socket d ’entrée

Scénario d’un client Créer le socket d ’entrée Créer un paquet de sortie Préparer et Envoyer une requête Créer un paquet d’entrée Attendre des données en entrée les recevoir et les traiter Fermer le socket d ’entrée

Datagrammes UDP et Sockets Datagramme = un message indépendant envoyé sur le réseau arrivée, temps d’arrivée et contenu non garantis 2 classes : DatagramPacket et DatagramSocket packages d’implémentation de communication via UDP de datagrammes

Exemple Un serveur de citation qui écoute un socket type datagram et envoie une citation si le client le demande Un client qui fait simplement des requêtes au serveur ATTENTION Plusieurs firewalls et routeurs sont configurés pour interdire le passage de paquets UDP

Une Application Client Serveur Le serveur reçoit en continu des paquets mode datagramme sur un socket un paquet reçu = une demande de citation d’un client le serveur envoie en réponse un paquet qui contient une ligne "quote of the moment" L’application cliente envoie simplement un paquet datagramme au serveur indiquant qu’il souhaite recevoir une citation et attend en réponse un paquet du serveur.

La classe QuoteServer socket = new DatagramSocket(4445); Création d’un DatagramSocket sur le port 4445 qui permet au serveur de communiquer avec tous ces clients try { in = new BufferedReader(new FileReader("one-liners.txt")); } catch (FileNotFoundException e) System.err.println("Couldn't open quote file. " + "Serving time instead."); } Le constructeur ouvre aussi un BufferedReader sur un fichier qui contient une liste de citations ( une citation par ligne)

suite contient une boucle qui tant qu’il y a des citations dans le fichier attend l’arrivée d ’un DatagramPacket correspondant à une requête client sur un DatagramSocket. Byte[] buf = new byte[256]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); En réponse une citation est mise dans un DatagramPacket et envoyée sur le DatagramSocket au client demandeur. String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes(); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); socket.send(packet);

Suite Adresse Internet + numéro de port (issus du DatagramPacket ) = identification du client pour que le serveur puisse lui répondre L’arrivée du DatagramPacket implique une requête ->contenu du buffer inutile Le constructeur utilisé pour le DatagramPacket : un tableau d’octets contenant le message et la taille du tableau + L’adresse Internet et un no de port. Lorsque le serveur a lu toutes les citations on ferme le socket de communication. socket.close();

La classe QuoteClient envoie une requête au QuoteServer, attend la réponse et affiche la réponse à l’écran. Variables utilisées : int port; InetAddress address; DatagramSocket socket = null; DatagramPacket packet; byte[] sendBuf = new byte[256]; Le client a besoin pour s ’exécuter du nom de la machine sur laquelle tourne le serveur if (args.length != 1) { System.out.println("Usage: java QuoteClient <hostname>"); return; }

La partie principale du main Création d ’un DatagramSocket DatagramSocket socket = new DatagramSocket(); Le constructeur lie le Socket à un port local libre Le programme envoie une requête au serveur byte[] buf = new byte[256]; InetAddress address = InetAddress.getByName(args[0]); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); Ensuite le client récupère une réponse et l’affiche

Classe DatagramSocket Des constructeurs : par défaut, + no port + Adresse Inet Des accesseurs en lecture : adresse à laquelle le socket est lié, est connecté, le no port auquel il est lié, connecté, taille du buffer reçu ou envoyé (getInetAddress, getLocalAddress, getPort, getLocalPort, getReceivedBufferSize, getSendBufferSize…) Des méthodes : pour se connecter à une adresse, pour se déconnecter, pour envoyer un paquet datagramme, pour un recevoir un paquet datagramme (connect, disconnect, send, receive)

Classe DatagramPacket Des constructeurs : buffer + longueur de buffer + adresse destination + port… Des accesseurs en lecture : adresse à laquelle le paquet est envoyé, le no port à laquelle le paquet est envoyé, la donnée transmise (getAddress, getPort, getData, getLength…)

Programmation Réseaux Illustration : Les Sockets en Java PARTIE 3 Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java

Communication par diffusion : Multicast Client1 Serveur Gr Client2 Clientn

Ouvrir un socket = demander à se Connecter Les clients demandent seulement à joindre un groupe

Exemple de multicast Un serveur de citation qui envoie une citation toutes les minutes à tous les clients qui écoutent (multicast)

Scénario d’un serveur Créer le socket d’entrée Créer un paquet de sortie Préparer et Envoyer une donnée Fermer le socket d’entrée

Scénario d’un client Créer le socket d’entrée Création d’un paquet d’entrée Attente de données en entrée Réception et traitement des données en entrée Fermer le socket d ’entrée

Classe MulticastServer Des constructeurs : par défaut, port à utiliser Des accesseurs en lecture : adresse du groupe (getInterface…) Des méthodes : pour envoyer un paquet datagramme, pour joindre ou quitter un groupe (send, joinGroup, leaveGroup)

Multicast: MulticastSocket Type de socket utilisé côté client pour écouter des paquets que le serveur « broadcast » à plusieurs clients. . Une extension du QuoteServer : broadcast à intervalle régulier à tous ses clients

Cœur du serveur while (moreQuotes) { try { byte[] buf new byte[256]; // don't wait for request...just send a quote String dString = null; if (in == null) dString = new Date().toString(); else dString = getNextQuote(); buf = dString.getBytes(); InetAddress group = InetAddress.getByName("230.0.0.1"); DatagramPacket packet; packet = new DatagramPacket(buf, buf.length, group, 4446); socket.send(packet); try {sleep((long)Math.random() * FIVE_SECONDS); } catch (InterruptedException e) { } } catch (IOException e) { e.printStackTrace(); moreQuotes = false;} } socket.close();}

Différences principales Le DatagramPacket est construit à partir de de « l’adresse de plusieurs clients » L ’adresse et le no de port sont câblés no de port 4446 (tout client doit avoir un MulticastSocket lié à ce no). L’adresse InetAddress "230.0.0.1" correspond à un identificateur de groupe et non à une adresse Internet de la machine d’un client Le DatagramPacket est destiné à tous les clients qui écoutent le port 4446 et qui sont membres du groupe "230.0.0.1".

Un nouveau Client Pour écouter le port 4446, le programme du client doit créer son MulticastSocket avec ce no. Pour être membre du groupe "230.0.0.1" le client adresse la méthode joinGroup du MulticastSocket avec l’adresse d’identification du groupe. Le serveur utilise un DatagramSocket pour faire du broadcast à partir de données du client sur un MulticastSocket. Il aurait pu utiliser aussi un MulticastSocket. Le socket utilisé par le serveur pour envoyer le DatagramPacket n’est pas important. Ce qui est important pour le broadcast est d’adresser l’information contenue dans le DatagramPacket, et le socket utilisé par le client pour l’écouter.

MulticastSocket socket = new MulticastSocket(4446); InetAddress group = InetAddress.getByName("230.0.0.1"); socket.joinGroup(group); DatagramPacket packet; for (int i = 0; i < 5; i++) { byte[] buf = new byte[256]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData()); System.out.println("Quote of the Moment: " + received); } socket.leaveGroup(group); socket.close();

Synthèse Client Serveur TCP aSocket aServerSocket connecté write read I/O Stream I/O Stream TCP aSocket aServerSocket connecté write read read write UDP aDatagramSocket aDatagramSocket non connecté send receive receive send Multicast aMulticastSocket aDatagramSocket/ aMulticastSocket aDatagramPacket

Quelques Informations utiles sur la sérialisation Java

Sérialisation-Desérialisation Enregistrer ou récupérer des objets dans un flux Persistance Transfert sur le réseau

Sérialisation Via la méthode writeObject() Classe implémentant l’interface OutputObject Exemple : la classe OutputObjectStream Sérialisation d’un objet -> sérialisation de tous les objets contenus par cet objets Un objet est sauvé qu’une fois : cache pour les listes circulaires

Desérialisation Via la méthode readObject() Classe implémentant l’interface InputObject Exemple : la classe InputObjectStream

Exception NotSerializableException Si la classe de l’objet sauvé N’étend ni l’interface Java Serializable Ni l’interface Java Externalizable

Interface Serializable Ne contient pas de méthode -> enregistrement et récupération de toutes les variables d’instances (pas de static) + informations sur sa classe (nom, version), type et nom des variables 2 classes compatibles peuvent être utilisées Objet récupéré = une copie de l’objet enregistré

Gestion de la sérialisation desérialisation Implémenter les méthodes private void writeObject(OutputObjectStream s) throws IOException private void readObject(OutputInputStream s) throws IOException defaultReadObject() et defaultWriteObject() méthodes par défaut Ajout d’informations à l’enregistrement, choix de sérialisation Seulement pour les champs propres de la classe (héritage géré automatiquement)

Gestion complète de la sérialisation desérialisation : utiliser Externalizable Graphe d’héritage complet Implémenter les méthodes public void writeExternal(ObjectOutput o) throws IOException public void readExternal(ObjectInput o) throws IOException ATTENTION PBM de SECURITE

Un peu plus de réflexivité Les ClassLoader ????

Classe ClassLoader ClassLoader est une classe abstraite. Un class loader est un objet responsable du chargement des classes Un nom de classe donné, il peut localiser ou générer les données qui constituent une définition de la classe. Chaque objet Class a une référence à un ClassLoader qui le définit. Applications implémentent des sous classes de ClassLoader afin d’étendre la façon de dynamiquement charger des classes par la VM. (utilisation de manager de sécurité, par exemple)

ClassLoader ? En UNIX la VM charge les classes à partir des chemins définis dans CLASSPATH. Certaines classes peuvent être obtenues à partir d’autres sources, telles que le réseau ou construites par une application. La méthode defineClass convertit un tableau d’octets en une instance de Class. Instances pouvant être créées grâce à newInstance Les méthodes et constructeurs créés par un class loader peuvent référencer d’autres classes (loadClass du class loader de cette classe).

Exemple de chargement de classe Un class loader qui permet de charger des fichiers de classes via le réseau ClassLoader loader=new NetworkClassLoader(host,port); Object main= loader.loadClass("Main", true).newInstance(); …. NetworkClassLoader doit définir findClass et loadClassData pour charger et defineClass pour créer une instance de Class.

Utilité et utilisation RMI

Chargement dynamique des classes Problème de sécurité Le programme client télécharge du code sur le réseau Ce code pourrait contenir des virus ou effectuer des opérations non attendues !!! Utilisation d ’un gestionnaire de sécurité pour les applications de clients RMI Possibilité de créer des gestionnaires de sécurité personnalisés pour des applications spécifiques RMI fournit des gestionnaires de sécurité suffisants pour un usage classique

Chargement dynamique Pour ne plus déployer les classes du serveur chez le client Utilisation des chargeurs de classes qui téléchargent des classes depuis une URL Utilisation d ’un serveur Web qui fournit les classes Ce que ça change Bien entendu, les classes et interfaces de l’ objet distant ne changent pas Le code du serveur ne change pas le client et la façon de le démarrer sont modifiés Et lancer un serveur Web pour nos classes

Hello World : chargement dynamique Séparation des classes Serveur (fichiers nécessaires a l'exécution du serveur) HelloWorldServer.class HelloWorldImpl.class HelloWorld.class HelloWorldImpl_Stub.class Download (fichiers de classes à charger dans le programme client) Client (fichiers nécessaires au démarrage du client) HelloWorldClient.class

Hello World : Démarrage du serveur Web Mettre les classes Download dans le répertoire des documents Web du serveur Web, accessibles via une URL le chargeur de classes ira chercher les classes à un emplacement de type http://www.class-server.com/classes/HelloWorldImpl_Stub.class };

Hello World : Politiques de sécurité Le programme Java client doit pouvoir se connecter aux ports de la base de registres RMI et des implémentations des objets de serveur, ainsi qu'au port du serveur Web Fichier client.policy grant { permission java.net.SocketPermission "*:1024-65535", "connect,resolve"; "*:80", "connect"; };

Hello World : gestionnaire de sécurité RMI Le client intègre un gestionnaire de sécurité RMI pour les stubs téléchargés dynamiquement import java.rmi.*; import java.rmi.server.*; public class HelloWorldClient { public static void main(String[] args) { try { // Installe un gestionnaire de sécurité RMI System.setSecurityManager(new RMISecurityManager()); System.out.println("Recherche de l'objet serveur..."); HelloWorld hello = (HelloWorld)Naming.lookup("rmi://server/HelloWorld"); System.out.println("Invocation de la méthode sayHello..."); String result = hello.sayHello(); System.out.println("Affichage du résultat :"); System.out.println(result); } catch(Exception e) { e.printStackTrace(); }

Hello World : Démarrage coté serveur 1) Lancer la base de registres RMI (elle doit pouvoir accéder aux classes Download - CLASSPATH) > rmiregistry 2) Lancer le serveur Web servant les fichiers de classes Download 3) Lancer le serveur (les classes Server doivent être accessibles) > java HelloWorldServer Création de l'objet serveur... Référencement dans le RMIRegistry... Attente d'invocations - CTRL-C pour stopper

Hello World : Démarrage coté client Le client doit pouvoir se connecter à des machines distantes pour la base de registres RMI, les objets de serveur ainsi que le serveur Web On doit lui fournir un fichier client.policy Le client doit bien connaître l'emplacement des classes afin de pouvoir les télécharger On va le lui préciser lors du lancement > java -Djava.security.policy=client.policy -Djava.rmi.server.codebase=http://www.class-server.com:80/ HelloWorldClient

Les méthodes d’une classe ? 1. récupérer l ’objet Class que l’on souhaite observer, 2. récupérer la liste des objets Method par getDeclaredMethods : méthodes définies dans cette classe (public, protected, package, et private) getMethods permet d’obtenir aussi les informations concernant les méthodes héritées 3. A partir des objets méthodes il est facile de récupérer : les types de paramètres, les types d’exception, et le type de l’argument retourné sous la forme d’un type fondamental ou d’un objet classe.

Exemple de programme Class cls = Class.forName("method1"); Method methlist[] = cls.getDeclaredMethods(); for (int i = 0; i < methlist.length; i++) { Method m = methlist[i]; System.out.println("name = " + m.getName()); System.out.println("decl class = " + m.getDeclaringClass()); Class pvec[] = m.getParameterTypes(); for (int j = 0; j < pvec.length; j++) System.out.println("param #" + j + " " + pvec[j]); Class evec[] = m.getExceptionTypes(); for (int j = 0; j < evec.length; j++) System.out.println("exc #" + j + " " + evec[j]); System.out.println("return type = " + m.getReturnType());}

Exemple d’exécution public class method1 { private int f1(Object p, int x) throws NullPointerException {……..} public static void main(String args[]) {….} name = f1 decl class = class method1 param #0 class java.lang.Object param #1 int exc #0 class java.lang.NullPointerException return type = int name = main param #0 class java.lang.String return type = void

Programmation Réseaux Illustration : Les Sockets en Java PARTIE 4 Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java

Définir un nouveau type de socket Pourquoi ? Préparer les données avant de les envoyer Reconstruire les données reçues Exemple Java RMI Sockets spécialisées (marshalling et unmarshalling) Exemple Images : Compression et Décompression Comment ? En spécialisant les classes de base

Comment Définir un nouveau type de Sockets La classe CompressionSocket et ses classes relatives 4 étapes Communication TCP Définir des E/S Spécifiques 1. Etendre java.io.FilterOutputStream pour créer un output stream pour ce type de Socket. Surcharge de méthodes si nécessaire. Le write doit compresser l’image avant d’écrire 2. Etendre java.io.FilterInputStream Le read doit décompresser après avoir lu

Comment Définir un nouveau type de Sockets La classe CompressionSocket et ses classes relatives 4 étapes 3. Etendre java.net.Socket Implémenter les constructeurs appropriés et surcharger getInputStream, getOutputStream et close. 4. Etendre java.net.ServerSocket Implémenter le constructeur et surcharger accept pour créer un socket du bon type.

Un « nouveau » Package : java.nio Les principales nouveautés de cette API sont : Buffers : qui explicitent la notion de buffers – containers de données Améliorent les problème de bufferisation liées aux E/S Charsets : qui associent des « décodeurs » et des « encodeurs » qui gèrent correctement les conversions chaines – octets Éliminent les problème de accent (caractères Unicode / UTF),

Un « nouveau » Package : java.nio Channels : qui représentent des connexions entre entités avec de meilleures performances pour les opérations de lecture et d’écriture Selectors et selection keys : associées aux selectable channels définissent des E/S multiplexées non bloquantes évitent les threads

Le package Channel SelectableChannel : canal qui peut être multiplexé DatagramChannel Un canal dédié aux communication UDP prises en charge par des sockets de type java.net.DatagramSocket   ServerSocketChannel  : Un canal dédié aux connexion TCP prises en charge par des sockets de type java.net.ServerSocket   SocketChannel : Un canal dédié aux communication TCP prises en charge par des sockets de type java.net.Socket

Le package Channel Et aussi… Selector Un multiplexeur pour des SelectableChannel SelectionKey représentant un canal étiqueté pour le multiplexage Pipe Deux canaux pour construire un pipe unidirectionnel (| shell)

Les nouvelles sockets Ce package définit des classes de canaux qui sont utilisables par les classes de sockets : DatagramSocket, ServerSocket, et Socket de java.net package. In all cases, un canal est créé par appel à une méthode statique open définie dans chaque classe. La socket est créée par egget de bord.

Exemple : Serveur d’heure import java.io.*; import java.net.*; import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; import java.util.*; import java.util.regex.*;

Exemple : initialisations public class TimeServer { private static int PORT = 8013; private static int port = PORT; // Charset and encoder for US-ASCII private static Charset charset = Charset.forName("US-ASCII"); private static CharsetEncoder encoder = charset.newEncoder(); // Direct byte buffer for writing private static ByteBuffer dbuf = ByteBuffer.allocateDirect(1024);

Exemple : attente de connexion sur le port du service // Open and bind the server-socket channel private static ServerSocketChannel setup() throws IOException { ServerSocketChannel ssc = ServerSocketChannel.open(); InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port); ssc.socket().bind(isa); return ssc; }

Exemple : communication avec un client // Service the next request to come in on the given channel // private static void serve(ServerSocketChannel ssc) throws IOException { SocketChannel sc = ssc.accept(); try { String now = new Date().toString(); sc.write(encoder.encode(CharBuffer.wrap(now + "\n"))); System.out.println(sc.socket().getInetAddress() + " : " + now); sc.close(); } finally { // Make sure we close the channel (and hence the socket) sc.close(); } }

Exemple : code du serveur public static void main(String[] args) throws IOException { if (args.length > 1) { System.err.println("Usage: java TimeServer [port]"); return; } // If the first argument is a string of digits then we take that // to be the port number if ((args.length == 1) && Pattern.matches("[0-9]+", args[0])) port = Integer.parseInt(args[0]); ServerSocketChannel ssc = setup(); for (;;) serve(ssc); } }

Conclusion Une large bibliothèque pour traiter les sockets et différents types de communication entre Clients et Serveurs dans Java Une extension naturelle par abstraction à l’appel de méthodes à distance - Java RMI et une normalisation Corba avec l’intégration d’un ORB (cf aaplications réparties 2nd semestre) et maintenant les EJB : Entreprise Java Beans

Retour sur RMI

Exemple CLIENT Essifun SERVEUR de Surnoms oter infrastructure Protocole d’application ?

Communication client serveur Connexion au serveur Attente de requêtes Préparation de la requête Envoi de la requête Attente du résultat …. Analyse du résultat reçu Analyse de la requête ….. Exécution …. Préparation de la réponse Envoi de la réponse

Exemple : annuaire des surnoms 1:Paul:bug ou ENR/nPaul/n/bug/n ou Objet Requête Seriablizable EssiFun SERVEUR de Surnoms enregistrer(« paul »,  «bug ») unmarshalling marshalling 0111000101000.. enregistrer(« paul »,  «bug ») = TRUE unmarshalling marshalling 101.. TRUE Différence entre un transport TCP et UDP pour le codage des données ?

Que peut on automatiser ? Au minimum, la phase de marshalling/unmarshalling (hétérogéneité des langages, des systèmes, etc) Selon les cas, le squelette du serveur les appels distants du client

Exemple : annuaire des surnoms et RMI AnnuaireEssi listePersonnes enregistrer lister oter Enregistrer(AnneMarie,AM) lister()

Exemple : annuaire des surnoms interface : partie visible de l’objet (enregistrer, oter, lister, …) implémentation : partie privée inaccessible depuis d’autres objets (listePersonnes : un vecteur de Personne ou un tableau ou ….) interface = contrat entre l’objet et le monde extérieur (save impossible par exemple)

RMI public interface Surnoms extends java.rmi.Remote { public Boolean enregistrer(String nom, String surnom) throws java.rmi.RemoteException, ServeurSurnoms.surnoms.ExisteDeja ; …. }

Générateurs Stubs Skeletons Proxy Spécifications des données Int. Java IDL Générateurs RMIC / Orbix... Fichiers générés Stubs Skeletons Proxy (mise en œuvre de la sérialisation et désérialisation…)

RMI Classes et Interfaces Remote Machine locale Machine distante InterfaceDistante InterfaceDistante Souche Squelette Appel méthode m() Appel méthode m() ClasseLocale ClasseDistante

Interaction Client Enregistreur serveur registre Lookup : où est objetDistant ? stub Il est ici Envoyez le stub Le voici squelette objet Distant result = objetDistant.m() result RMIRegistry + ClassLoader

Exemple : annuaire des surnoms ASN.1 et norme ISO Protocole := CHOICE { enregistrerReq [0] SEQUENCE{PrintableString nom, PrintableString surnom} enregistrerRep[1] BOOLEAN, listerReq [2] NULL, listerRep [3] SET OF Personnes, ….} XDR et RPC de SUN Programme surnoms { version { boolean enregistrer(nomSurnom) = 1; listePersonnes lister(void)=2 }= 1 } = 10000

Générateurs de Stubs Spécifications des données XDR ASN1 Générateurs RPCGEN / MAVROS Fichiers générés Types de données C Lisp Java Librairie marshalling et unmarshalling squelettes du client et du serveur Types de données C

Les points communs des approches distribuées Adressage : à tout serveur (objet ou programme) doit être affecté une référence unique Transport : pour établir une communication entre 2 nœuds et transmettre une requête Marshalling : transformation de la requête pour passer sur le réseau

Points communs Protocol : transmission des requêtes entre exécutables Dispatching : gestion des threads Des services communs Services de nommage Interface repository .....

Restent à approfondir

Communication réseaux et Internet Couches de transport Différences entre UDP et TCP (Développement d’un serveur multicast Ack/NoAck pour gérer la perte des paquets UDP) D’autres protocoles (RTP/RTCP) (introduction du routage multicast ou du tunelling) Principes du IP / protocole ICMP Service de nommage DNS Configuration services réseau

Spécificités des Réseaux Locaux Introduction au Réseaux Locaux LANs Configuration carte réseau d’une machine, Développement d’un analyseur de trafic et standards IEEE 802 : IEEE 802.3 et Ethernet Configuration d’un Firewall : IPTables, Heureusement Dino est là :-)

Quelques interrogations ? Comment choisir le bon middleware (intergiciel) ? Il y en a de plus en plus Corba, RMI, DCOM, DSA + CCM, J2EE + Web Services, .net .... Savoir les comparer Identifier les points communs Interopérabilité : XML une solution suffisante ? Heureusement Mireille est là 

Programmation Réseaux Qu’avez-vous retenu ? Anne-Marie Déry À travailler seuls Concepts généraux Mise en œuvre Java

Questions préliminaires Différences entre les protocoles de transport TCP et UDP ? Utilisation des adresses Internet ? Utilisation des ports ? Programmation sockets : avantages et inconvénients

Lien Types de Socket - Couche de transport

Des entrées sorties : Pourquoi ?

Différences UDP -TCP

Différences Protocole d’application marshalling

Quand doit on utiliser des threads ?

Différences Sockets Java - C

Apports du package nio

Protocole d’application RMI

Avantages – Inconvénients RMI Socket

Différence déploiement statique - dynamique

Impact de la Sérialisation d’objets Java sur la communication

Réflexivité Java où et pourquoi ?