10 Persistance, Sockets, Objets distribués
Notion de persistance, applicaiton pour les threads et les applets,
bibliothèque sur les sockets, copie d'objets via des sockets, objets distribuées : RMI et CORBA
Slide: 1
Persistance
conservation d'un objet en dehors de l'exécution courante :
dans un fichier ou un flux
But récupération ultérieure dans le même programme
ou un autre.
Difficultés :
- lecture/écriture de données
- structures circulaires
- coercion de type à la relecture
- sauvegarde de code
En jdk1.1 : mécanisme de sérialisation!!!
Slide: 2
Sérialisation
- classes de flux
- ObjectOutputStream : flux de sérialisation
- ObjectInputStream : flux de désérialisation
- interface
- Serializable : doit être implantée (vide) pour être sérialisé
Slide: 3
Que stocke-t-on?
Le stockage contient :
- le nom et une clé (checksum) de la classe
- tous les champs (de données) sérialisables
La clé permet de vérifier la version de la classe.
Le modifieur transient permet d'indiquer qu'un champs ne doit pas être sérialisé.
possibilité de changer le mécanisme de sérialisaiton en implantant une classe Externalizable respectant les interfaces writeExternal
et readExternal.
Slide: 4
Exemple
½ . =tô ..
Slide: 5
Exécution
java Execute
*
*
1 : truc::machin
2 : []
*
3 : bidule::truc::machin
*
: trace de ajoute(..)
Slide: 6
Programmation distribuée
Chaque processus gère sa propre mémoire et communique avec les autres via
un medium (protocoles).
------ /\ ------
| M1 |-----P1 <--> / \ <--> P3-----| M3 |
------ / \ ------
/medium\
----------
^
|
|
v
P2
|
|
------
| M2 |
------
La communication est explicite et la synchronisation est implicite :
¹ du modèle à mémoire partagée (threads).
Slide: 7
Internet*
organisation du réseau Internet :
----------------
| APPLICATIONS |
----------------
^ |
| |
| v
----------------
| UDP / TCP |
----------------
^ |
| |
| v
----------------
| IP/Interfaces|
----------------
^ |
| |
| v
----------------
| MEDIAS |
----------------
Slide: 8
Protocoles Internet
IPv4 : adresse sur 32 bits : chaque machine a une adresse unique
IP : protocole non fiable : traite juste le routage du datagramme.
UDP : (User Datagram Protocol) non fiable - non connecté (multiplexage)
TCP : (Transfert Control Protocol) protocole orienté connexion et fiable
Rightarrow gère les acquitements.
Slide: 9
Services Internet
utilisent le modèle client/serveur : le serveur est un programme offrant un service spécifique (il gère les requêtes des clients en établissant une connexion ou non selon le protocole.
asymétrie entre le client et le serveur.
Implantation de protocoles de plus haut niveau :
- FTP, TELNET, SMTP, HTTP
- autres c/s : NFS, X-window, rlogin, mysql
Coomunication entre applications via des prises (socket) de communication, à partir de plusieurs processus/machines. Différents processus peuvent lire et écrire dessus.
Slide: 10
Communication sur sockets
Le schéma classique d'un serveur est le suivant :
creation de ls socket (socket) : (TCP/UDP)
attachement de la socket (bind) :(ADR_IP,PORT)
ouverture du service (listen) : (nombre)
attente de connexion (accept) : (acceptation)
creation d'un processus (fork) : (ou thread)
proc : boucle sur l'attente de la connexion
newproc : traite la demande
et le client :
creation de la socket (socket) : (TCP/UDP)
connexion sur la prise : (ADR_IP_serv,PORT)
Slide: 11
Classes
paquetage : java.net : fournit un ensemble de classes pour communiquer sur le réseau Internet.
- classe de bas niveau : pour les couches basses (DatagramPacket,...)
- et de haut niveau : pour les clients/serveurs
La classe InetAddress représente les adresses Internet. Elle est utilisée dans la classe Socket. Les classes de haut niveau sont :
Slide: 12
Classes de haut niveau
- ServerSocket : méthode accept retourne une socket quand une demande est reçue;
- Socket (classe finale) : pour la communication à travers le réseau. Les méthodes getOutputStream() et getInputStream
permettent de récupérer les canaux de communication.
- URL : permet de dialoguer via une URL.
Slide: 13
Exemple de client/serveur
Conversion de chaînes en MAJUSCULE via un serveur (Java : de l'esprit à
la méthode)
Le serveur est construit à partir de 2 classes :
- Serveur : classe générique (au numéro du port près)
- Connexion : pour les canaux et le traitement
Lors d'une connexion d'un client au serveur (Serveur.run()) une nouvelle instance de Connexion est créée.
Slide: 14
Partie serveur
import java.io.*;
import java.net.*;
public class Serveur extends Thread {
protected static final int PORT =45678;
protected ServerSocket ecoute;
Serveur ()
{ try
{ ecoute = new ServerSocket(PORT);}
catch (IOException e)
{System.err.println(e.getMessage());
System.exit(1);
}
System.out.println(
"Serveur en ecoute sur le port : "+PORT);
this.start();
}
public void run ()
{ try
{while (true)
{Socket client=ecoute.accept();
Connexion c = new Connexion (client);}}
catch (IOException e)
{System.err.println(e.getMessage());
System.exit(1);}
}
public static void main (String[] args)
{new Serveur();}
}
Slide: 15
Partie Connexion
class Connexion extends Thread {
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
public Connexion(Socket client_soc)
{ client=client_soc;
try
{ in=new DataInputStream(client.getInputStream());
out=new PrintStream(client.getOutputStream());}
catch (IOException e)
{try {client.close();}
catch (IOException e1){}
System.err.println(e.getMessage());
return;}
this.start();
}
public void run()
{ try
{ while (true)
{String ligne=in.readLine();
if (ligne.toUpperCase().compareTo("FIN")==0) break;
System.out.println(ligne.toUpperCase());
out.println(ligne.toUpperCase());
out.flush();
}}
catch (IOException e)
{System.out.println("connexion : "+e.toString());}
finally
{try {client.close();} catch (IOException e) {}}
}
}
Slide: 16
Partie client
import java.io.*;
import java.net.*;
public class Client {
protected static final int PORT=45678;
public static void main(String[] args)
{
Socket s=null;
if (args.length != 1)
{System.err.println("Usage: java Client <hote>");
System.exit(1);}
try
{ s=new Socket (args[0],PORT);
DataInputStream canalLecture = new DataInputStream(s.getInputStream());
DataInputStream console = new DataInputStream (s.getInputStream());
PrintStream canalEcriture = new PrintStream(s.getOutputStream());
System.out.println("Connexion etablie : "+
s.getInetAddress()+" port : "+s.getPort());
String ligne = new String();
char c;
while (true)
{ System.out.print("?"); System.out.flush();
ligne = "";
while ((c=(char)System.in.read()) != '\n') {ligne=ligne+c;}
// ligne=ligne + '\n';;
canalEcriture.println(ligne);
canalEcriture.flush();
ligne=canalLecture.readLine();
if (ligne == null)
{System.out.println("Connexion terminee"); break;}
System.out.println("!"+ligne);
}
}
catch (IOException e) {System.err.println(e);}
finally
{ try {if (s != null) s.close();}
catch (IOException e2) {}
}
}
}
Slide: 17
Execution
[chaillou@ippc56]$ java Serveur
Serveur en ecoute sur le port : 45678
ADIEU
MONDE CRUEL
coté client
[chaillou@ippc56]$ java Client ippc56
Connexion etablie : ippc56/134.157.116.56 port : 45678
?adieu
!ADIEU
?monde cruel
!MONDE CRUEL
?fin
Connexion terminee
Slide: 18
Communication avancée
Pour établir un nouveau service, il est souvent nécessaire
de définir un ``protocole'' de communication entre le
serveur et les clients.
...
Slide: 19
Objets distribués
Possibilités
clients/serveurs + persistance Þ transport d'objets
par copie (et création de nouvelles instances)
Références distantes références de plusieurs endroits du réseau au même objet
pour invoquer ses métodes et/ou modifier ses variables d'instances.
Slide: 20
Difficultés de mise en oeuvre
- transparence référentielle
- Garbage Collector
- typage des objets copiés
- exceptions distantes
le jdk 1.1 offre un mécanisme simple nommé RMI (Remote Method Invokation) permettant de manipuler des objets distants.
Slide: 21
RMI
- objet distant : sur une autre machine virtuelle Java
- garde le même modèle objet
- utilisation d'interface étendant Remote
- passage de paramètre et résultat par copie (Serializable)
Slide: 22
Structure générale
client serveur
^ ^
| |
| |
| |
v v
--------------- ---------------
| stub | | skeleton |
-----------------------------------
| couche des references |
-----------------------------------
| couche transport |
-----------------------------------
Slide: 23
Serveur
Le serveur s'en trouve compliqué sur les services suivants :
- GC des objets distribués
- réplication d'objets distants
- activation d'objets persistants
Slide: 24
Paquetages
Les paquetages utiles sont :
- java.rmi : pour le coté client
- java.rmi.server : pour le coté serveur
- java.rmi.registry : pour l'utilisation d'un service d'enregistrement
et de référentiel des objets serveurs,
- tt java.rmi.dgc : pour le GC distribué.
L'interface d'objets distants étend l'interface Remote en ajoutant les méthodes désirées qui peuvent déclencher des RemoteException.
Slide: 25
Exemple : Points distants
Interface
import java.rmi.*;
public interface PointRMI extends Remote {
void moveto (int a, int b) throws RemoteException;
void rmoveto (int dx, int dy) throws RemoteException;
void affiche() throws RemoteException;
double distance() throws RemoteException;
}
Slide: 26
Implantation d'interfaces distantes
Implantation de l'interface
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class PointD extends UnicastRemoteObject
implements PointRMI {
int x,y;
PointD(int a, int b) throws RemoteException {x=a;y=b;}
PointD() throws RemoteException {x=0;y=0;}
public void moveto (int a, int b)
throws RemoteException
{ x=a; y=b;}
public void rmoveto (int dx, int dy)
throws RemoteException
{ x = x + dx; y = y + dy;}
public void affiche()
throws RemoteException
{ System.out.println("(" + x + "," + y + ")");}
public double distance()
throws RemoteException
{ return Math.sqrt(x*x+y*y);}
}
Slide: 27
Compilation
- interface et implantation par : javac
- stubs et skeletons par : rmic de la manière suivante :
rmic PointD
qui créera les fichiers PointD_Stub.class
et
PointD_Skel.class
.
Slide: 28
création et enregistrements
Le serveur de points lui va créer des instances de PointD et les enregistrer (rebind)
auprès du démon (rmiregistery) qui gère le protocole rmi.
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class Creation {
public static void main (String args[]) {
System.setSecurityManager(new RMISecurityManager());
try {
PointD p0 = new PointD();
PointD p1 = new PointD(3,4);
Naming.rebind("//youpou.lip6.fr/point0",p0);
Naming.rebind("//youpou.lip6.fr/point1",p1);
System.out.println("Objets distribues 'p0' " +
"et 'p1' sont enregistres");
}
catch (Exception e) { e.printStackTrace();
}
}
}
Slide: 29
Commentaires
- le ``security manager'' garantit (??) qu'il n'y aura pas d'opérations illégales.
- l'enregistrement nécessite de nommer chaque instance
La classe Naming permet de nommer des objets pour leur enregistrement sur le serveur (bind,
rebind, unbind, list, lookup).
Compilation classique avec javac.
Slide: 30
un client
import java.rmi.*;
public class Client {
public static void main( String argv[]) {
String url0="rmi://youpou.lip6.fr/point0";
String url1="rmi://youpou.lip6.fr/point1";
try {
PointRMI p0 = (PointRMI)Naming.lookup(url0);
PointRMI p1 = (PointRMI)Naming.lookup(url1);
p0.affiche(); p1.affiche();
p0.rmoveto(7,12);
p1.rmoveto(5,6);
p0.affiche(); p1.affiche();
if (p0.distance() == p1.distance())
System.out.println("c'est le hasard");
else
System.out.println("on pouvait parier");
}
catch (Exception e) {
System.err.println("exception : " +
e.getMessage());
e.printStackTrace();
} } }
Slide: 31
Exécution
1ère exécution
(0,0)
(3,4)
(7,12)
(8,10)
on pouvait parier
2ème exécution
(7,12)
(8,10)
(14,24)
(13,16)
on pouvait parier
Slide: 32
Exceptions
Si le démon ne fonctionne plus au moment de l'utilisation d'un objet distant, on récupère l'exception dans le catch et on affiche les messages suivants :
exception : Connection refused to host;
...
et si l'objet demandé n'est pas enregistré, la suivante :
exception : point0
java.rmi.NotBoundException: point0
Slide: 33
port de communication
Par défaut, le port du service rmi est le 1099. Il est possible de changer de numéro. Pour cela
le serveur d'enregistrement doit être lancé avec le paramètre du port :
rmiregistry 2000&
et il faut indiquer ce nouveau port aux URL employées :
//youpou.lip6.fr:2000
Slide: 34
CORBA
Common Object Request Broker Architecture : norme (OMG - 1990)
permettant :
- d'être indépendant des langages
- d'avoir des services d'enregistrements plus complets
- de ne pas dépendre d'un constructeur :
de nombreux ORB, y compris gratuit
Pour être indépendant CORBA définit le langage IDL.
Slide: 35
IDL
Langage de définition d'interfaces qui permet de décrire les
méthodes et champs visibles des objets.
Accepte l'héritage simple et multiple d'interfaces.
Point
interface Point {
void moveto(in int a, in int b);
void rmoveto(in int dx, in int dy);
void affiche();
double distance();
}
A partir de cette description, le compilateur IDL (fourni avec un ORB), engendreles
stubs et les skeletons pour le serveur et cela pour différents langages (Smalltalk, C++, Java ...)
This document was translated from LATEX by HEVEA.