Sockets ?

publicité
Programmation Réseaux
Illustration : Les Sockets en Java
À travailler seuls
Concepts généraux
Mise en œuvre Java
Anne-Marie Déry
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
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
application
send request
send reply
opération
« 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
DatagramSocket
ServerSocket
MulticastSocket
Socket
Des exceptions
Exception
IOException
SocketException
ProtocolException
UnknownHostException UnknownServiceException
BindException
ConnectException
Des Entrées Sorties
Object
InputStream
OutputStream
FileInputStream
ObjectInputStream
FileOutputStream
ObjectOutputStream
FilterInputStream
FilterOutputStream
DataInputStream
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
Point de vue application
TCP fournit un transfert fiable,
conservant l’ordre de transfert
des octets (“pipe”)
entre le client et le serveur
Client
Serveur
Ouvrir connexion
req1
req2
req3
application
reqn
Fermer la connexion
opération
Interaction Client/server :
socket TCP
create socket,
port=x, for
incoming request:
welcomeSocket =
ServerSocket()
TCP
wait for incoming
connection request connection
connectionSocket =
welcomeSocket.accept()
read request from
connectionSocket
write reply to
connectionSocket
close
connectionSocket
Serveur (s’exécutant sur l’hôte)
setup
create socket,
connect to hostid, port=x
clientSocket =
Socket()
send request using
clientSocket
read reply from
clientSocket
close
clientSocket
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
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
Créer le socket de connexion
avec le serveur
Attendre que la connexion
soit établie
Récupérer la socket de
communication
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
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
output.close();
input.close();
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: <[email protected]>\n");
os.writeBytes("RCPT To: <[email protected]>\n");
os.writeBytes("DATA\n");
os.writeBytes("From: [email protected]\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
create socket,
port=x, for
incoming request:
welcomeSocket =
ServerSocket()
TCP
wait for incoming
connection request connection
connectionSocket =
welcomeSocket.accept()
read request from
connectionSocket
write reply to
connectionSocket
close
connectionSocket
Serveur (s’exécutant sur l’hôte)
setup
create socket,
connect to hostid, port=x
clientSocket =
Socket()
send request using
clientSocket
read reply from
clientSocket
close
clientSocket
Client
Plusieurs Clients
Utiliser des threads pour accepter plusieurs clients
simultanément.
Le serveur gère un thread par client
Plusieurs clients
Client1
Serveur
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
À travailler seuls
Concepts généraux
Mise en œuvre Java
Anne-Marie Déry
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
Adresse internet
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
157.169.20.5
157.169.20.4
157.169.25.201
157.169.10.222
157.169.4.50
157.169.10.120
157.169.10.240
157.169.1.20
157.169.25.110
157.169.1.153
157.169.3.204
157.169.1.155
157.169.10.2
oscar.essi.fr oscar
accueil.essi.fr accueil
compta.essi.fr compta
www-local.essi.fr www-local
pcprofs.essi.fr pcprofs
ada.essi.fr ada
macserver.essi.fr macserver
demo.essi.fr demo
bibli.essi.fr bibli
sfe-srv.essi.fr sfe-srv sfe
bde.essi.fr bde
niv1a.essi.fr niv1a
dessi.essi.fr dessi
jessica.essi.fr jessica print2
ypcat hosts sous linux
Exemples d ’adresses
157.169.25.200
134.59.132.21
157.169.10.1
news-srv.essi.fr news-srv www.essi.fr
www-srv.essi.fr news
dolphin.unice.fr
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
UDP
Serveur FTP : 21
Serveur Telnet : 23
Serveur SMTP : 25
Serveur multi processus
Agent SNMP : 161
Logger SNMP : 162
….
Applications transactionnelles
Programmation Socket
Comment construire des applications client/server qui
communiquent via les sockets
socket
• Deux types de transports
via les socket API:
– Datagramme (non
reliable)
– Orienté flux d’octets
(reliable)
Une porte à travers
laquelle l’application peut
à la fois envoyer et
recevoir des messages
d’une autre application
Programmation socket avec TCP
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 clientlocalement
• Spécifiant l’adresse et le no
de port number du processus
serveur
• 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
Applications distribuées et
parallèlisme
La communication ne doit pas rester
bloquée pour un client
Interaction Client/server :
socket TCP
create socket,
port=x, for
incoming request:
welcomeSocket =
ServerSocket()
TCP
wait for incoming
connection request connection
connectionSocket =
welcomeSocket.accept()
read request from
connectionSocket
write reply to
connectionSocket
close
connectionSocket
Serveur (s’exécutant sur l’hôte)
setup
create socket,
connect to hostid, port=x
clientSocket =
Socket()
send request using
clientSocket
read reply from
clientSocket
close
clientSocket
Client
Plusieurs Clients
Utiliser des threads pour accepter plusieurs clients
simultanément.
Le serveur gère un thread par client
Plusieurs clients
Client1
Serveur
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
req1
rep1
application
reqn
repn
opération
Programmation Socket avec UDP
UDP: pas de “connexion” entre
le client et le serveur
application viewpoint
UDP fournit un transfert
• Pas de lien privilégié entre le
non fiable de groupes d’octets
client et le serveur
(“datagrammes”)
entre un 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
UDP: les données transmises peuvent être
datagramme reçu
reçues dans le désordre ou perdues
Client/server socket interaction: UDP
create socket,
port=x, for
incoming request:
serverSocket =
DatagramSocket()
read request from
serverSocket
write reply to
serverSocket
specifying client
host address,
port umber
Serveur
create socket,
clientSocket =
DatagramSocket()
Create, address (hostid, port=x,
send datagram request
using clientSocket
read reply from
clientSocket
close
clientSocket
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
req1
rep1
application
reqn
repn
opération
Programmation Socket avec UDP
UDP: pas de “connexion” entre
le client et le serveur
application viewpoint
UDP fournit un transfert
• Pas de lien privilégié entre le
non fiable de groupes d’octets
client et le serveur
(“datagrammes”)
entre un 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
UDP: les données transmises peuvent être
datagramme reçu
reçues dans le désordre ou perdues
Client/server socket interaction: UDP
create socket,
port=x, for
incoming request:
serverSocket =
DatagramSocket()
read request from
serverSocket
write reply to
serverSocket
specifying client
host address,
port umber
Serveur
create socket,
clientSocket =
DatagramSocket()
Create, address (hostid, port=x,
send datagram request
using clientSocket
read reply from
clientSocket
close
clientSocket
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
À travailler seuls
Concepts généraux
Mise en œuvre Java
Anne-Marie Déry
Communication par diffusion :
Multicast
Client1
Serveur
Client2
Gr
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
I/O Stream
I/O Stream
TCP
connecté
aSocket
write
read
aServerSocket
read
write
aDatagramPacket
UDP
aDatagramSocket
non connecté
send
receive
Multicast
receive
send
aMulticastSocket
receive
aDatagramSocket
aDatagramSocket/
aMulticastSocket
send
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)
• HelloWorldImpl_Stub.class
– Client (fichiers nécessaires au démarrage du client)
• HelloWorld.class
• 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";
permission java.net.SocketPermission
"*: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.NullPointerExcept
return type = int
name = main
decl class = class method1
param #0 class java.lang.String
Programmation Réseaux
Illustration : Les Sockets en Java
PARTIE 4
À travailler seuls
Concepts généraux
Mise en œuvre Java
Anne-Marie Déry
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("USASCII");
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
CLIENT
Connexion au serveur
Préparation de la requête
Envoi de la requête
Attente du résultat
….
Analyse du résultat reçu
SERVEUR
Attente de requêtes
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 »)
marshalling 0111000101000..
unmarshalling
TRUE
101..
unmarshalling
enregistrer(« paul »,
«bug ») = TRUE
marshalling
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(AnneMarie,AM)
lister()
enregistrer
lister
oter
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
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
Machine locale
Machine distante
InterfaceDistante
InterfaceDistante
Souche
Squelette
Appel méthode m()
Appel méthode m()
ClasseLocale
Remote
ClasseDistante
Interaction Client Enregistreur
Lookup : où est objetDistant ?
client
registre
Il est ici
result
Envoyez le stub
stub
Le voici
stub
result = objetDistant.m()
squelette
objet
Distant
RMIRegistry + ClassLoader
client
serveur
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 Types de
générés 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 ?
À travailler seuls
Concepts généraux
Mise en œuvre Java
Anne-Marie Déry
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 ?
Téléchargement