À travailler seuls Concepts généraux Mise en œuvre Java Année 2011-2012.
-
Upload
tristram-garin -
Category
Documents
-
view
104 -
download
1
Transcript of À travailler seuls Concepts généraux Mise en œuvre Java Année 2011-2012.
Programmation RéseauxIllustration : Sockets en Java
Anne-Marie Dé[email protected]
À travailler seuls
Concepts généraux
Mise en œuvre Java
Année 2011-2012
Réseau et département SI
Programmation RéseauxSockets Java
Introduction aux applications réparties
Couches Réseaux : protocoles TCP – UDPSockets C
Programmation par ComposantsExpériences IndustriellesAdministration et sécurité des réseaux
Réseaux sans filApplications Temps Réel
Questions préliminaires
Protocoles de transport TCP et UDP ?
Utilisation des adresses Internet ?
Utilisation des ports ? Programmation sockets :
gestion d’entrées/sorties
Client : ?Serveur : ?Serveur de noms ?(DNS, LDAP) ?
Besoins d’une application Client-Serveur
Similitudes avec un appel téléphonique via un standard1. Trouver l’adresse du serveur : trouver le no de téléphone de l’entreprise2. 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 vocabulaireClient : entité qui fait l’appelSockets : moyen de communication entre ordinateursAdresses IP : adresse d’un ordinateurServeur : entité qui prend en charge la requêteServeur de noms (DNS) : correspondances entre noms logiques et adresses IP (Annuaire)Port : canal dédié à un serviceProtocole : langage utilisé par 2 ordinateurs pour communiquer entre eux
protocole de transport : comment véhiculer les données – construction de la trame réseau
protocole d’application : comment le client et le serveur structurent les données échangées
Adresse Internet et Port
Adresse internet attribuée à chaque nœud du réseausérie d ’octets dont la valeur dépend du type de réseauassociée à un nom logique (Domain Name Server)
Chaque hôte possède environ 65535 ports
Port canal dédié à un service spécifique80 pour le service http25 pour le service SMTP En savoir plus ?
Ports réservés
TCPServeur FTP : 21Serveur Telnet : 23Serveur SMTP : 25
UDPAgent SNMP : 161Logger SNMP : 162Serveur rwhod : 513
Serveur multi processus Applications transactionnelles
1 à 1024 services fondamentaux (administrateurs)1025 à 5000 disponibles pour les utilisateurs
Exemples d ’adresses Internet
Résultats d’une recherche dans un DNS
157.169.9.15 oscar.essi.fr oscar157.169.20.5 accueil.essi.fr accueil157.169.20.4 compta.essi.fr compta157.169.25.201 www-local.essi.fr www-local157.169.10.222 pcprofs.essi.fr pcprofs157.169.4.50 ada.essi.fr ada157.169.10.120 macserver.essi.fr macserver157.169.10.240 demo.essi.fr demo157.169.1.20 bibli.essi.fr bibli157.169.25.110 sfe-srv.essi.fr sfe-srv sfe157.169.1.153 bde.essi.fr bde157.169.3.204 niv1a.essi.fr niv1a157.169.1.155 dessi.essi.fr dessi157.169.10.2 jessica.essi.fr jessica print2
Exemples d ’adresses
157.169.25.200 news-srv.essi.fr news-srv www.essi.fr www-srv.essi.fr news134.59.132.21 dolphin.unice.fr157.169.10.1 essi2.essi.fr loghost essi2
Essi : 157.169I3S: 134.59serveurs : 25Administration : 20…….
En savoir plus ?
Comment trouver les adresses ip ?
ipconfig sous Windowsifconfig sous linux
Exemple du modem ADSL (Freebox, LiveBox, etc.), deux interfaces réseau : une interface privée, servant à mettre en réseau les ordinateurs connectés à la Freebox. Adresse IP du type 192.168.0.* ou 192.168.1.*.
A l’école adresses privées respectant le protocole ipV4
En savoir plus ?
Architecture client serveur
Mode de communication qu’un hôte établit avec un autre hôtequi fournit un service quelconque
applicationopération
Client
Serveur
send request
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 au
dessus d’un protocole de transport
Programmation 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
socket
Comment construire des applications client/server qui communiquent via les sockets
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) etdes fichiers
Un socket : une entrée sortie dédiée au réseau
Gestion similaire des entrées sorties standard (écran, clavier) etdes 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 TCP
- fortement connectée - synchrone - type client-serveur
pour communication réseau par message UDP- en mode datagramme - en mode déconnecté
pour communication réseau par diffusion UDP
Exemples d’applications
Un serveur d’Echo Un exemple : le service SMTP
Demande de citations Diffusion de citations
Sockets en Java ?
Au dessus de TCP ou UDP
En Java toutes les classes relatives aux socketssont dans le package java.net
Une infrastructure puissante etflexible pour la programmation réseau
Le Package net
Des Exceptions Des entrées Sorties Des Sockets …...
Plusieurs hiérarchies de classes
Des types de Sockets
ServerSocket DatagramSocket
MulticastSocket
Socket
Object
Des exceptions
Exception
IOException
SocketException ProtocolException UnknownHostException UnknownServiceException
BindException ConnectException
Des Entrées Sorties
Object
InputStream
FileInputStream ObjectInputStream
OutputStream
FileOutputStream
ObjectOutputStream
FilterInputStream
DataInputStreamFilterOutputStream
DataOutputStream
Autres Classes
Object
InetAdress DatagramPacket SocketImpl
PlainSocketImpl
Java.net.InetAddress : nommageLa 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 lamachine 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
applicationopération
Client
Serveur
Ouvrir connexionreq1req2req3
reqn
Fermer la connexion
TCP fournit un transfert fiable, conservant l’ordre de transfert
des octets (“pipe”) entre le client et le serveur
Point de vue application
Interaction Client/server :socket TCP
Serveur (s’exécutant sur l’hôte) Client
wait for incomingconnection requestconnectionSocket =welcomeSocket.accept()
create socket,port=x, forincoming request:welcomeSocket =
ServerSocket()
create socket,connect to hostid, port=xclientSocket =
Socket()
closeconnectionSocket
read reply fromclientSocket
closeclientSocket
send request usingclientSocketread request from
connectionSocket
write reply toconnectionSocket
TCP connection setup
Scénario d’un serveurpour un client
Attente de données sur le flux d’entréeRéception et Analyse des données en entréeCalculConstruction de la réponseEcriture sur le flux de sortie
Fermer le socket de communication
Créer le socket de communication avec le client
Scénario d’un client
Préparer la requêtel’envoyer sur le flux de sortieAttendre des données sur le flux d’ entrée les lire et les traiter
Fermer le socket
Créer le socket de connexionavec le serveurAttendre que la connexion soit établieRécupérer la socket de communication
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éesConnexion +
« Marshalling »
Accepter les connexions Dans un serveur ?
Créer un objet socket pour écouter les demandes de connexionsur le numéro de port associé au service
Créer un objet socket pour accepter une connexion d ’un clientcet objet servira pour tous les transferts d ’information de
ce client vers le serveur
Dans un serveur ?Accepter les connexionsServerSocket 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 clientidentifier 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 serveurCô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 clientExemple 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, desdoubles,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()));
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é clientCô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 connecte le client sur un nouveau no de portet reste en attente sur le port original
Client et serveur communiquent en écrivant et lisant sur un socket
Le serveur est à l’écoute des requêtes sur un port particulierUn client doit connaître l’hôte et le port sur lequel le serveur écoute. Le client peut tenter une connexion au serveur
Serveur Echo
Un serveur similaire à echo ( port 7). Reçoit un texte du client et le renvoie identiqueLe 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 étapesOuvrir 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);} } } }
.
Avez-vous suivi ?
Quel est le protocole d’application pour le service SMTP ?peut-on le changer ?
Quel est l’entrée du service sur la machine hôte ?peut-on la changer ?
Quelle est le marshalling associé au protocole d’application ?peut-on le changer ?
Quel est le protocole de transport ?peut-on le changer ?
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 lequelle 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
Serveur (s’exécutant sur l’hôte) Client
wait for incomingconnection requestconnectionSocket =welcomeSocket.accept()
create socket,port=x, forincoming request:welcomeSocket =
ServerSocket()
create socket,connect to hostid, port=xclientSocket =
Socket()
closeconnectionSocket
read reply fromclientSocket
closeclientSocket
send request usingclientSocketread request from
connectionSocket
write reply toconnectionSocket
TCP connection setup
Plusieurs Clients
Utiliser des threads pour accepter plusieurs clients simultanément.
Le serveur gère un thread par client
Plusieurs clients
application
Clientn
ServeurOuvrir connexion
application
Client1
application
Client2 S1
S2
Sn
Quelques mots sur les ThreadsUn thread permet l’exécution d’un programme. Une application peut avoir de multiples threads qui s ’exécutentconcurremment (Chaque thread a une priorité). Chaque thread a un nom. Plusieurs threads peuvent avoir lemême. Le nom est généré si non spécifié. Il y a 2 façons de créer un thread d’exécution.
déclarer une sous classe de Thread et surchargerla méthode run. Une instance de la sous classe peut alorsêtre allouée et démarrée.
déclarer une classe qui implémente Runnable et doncla méthode run. Une instance de la classe peut être allouée, passée comme argument à la création d’un threadet démarrée.
while (true) { accept a connection ; create a thread to deal with the client ; end while
Scénario du Serveur Multithreadé
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(); } }
Communication asynchrone par messagesCommunication par diffusion
Communication par message : Envoi de datagrammes
applicationopération
Client
Serveur
req1rep1
reqnrepn
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 viewpointUDP 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
closeclientSocket
Serveur
read reply fromclientSocket
create socket,clientSocket = DatagramSocket()
Create, address (hostid, port=x,send datagram request using clientSocket
create socket,port=x, forincoming request:serverSocket = DatagramSocket()
read request fromserverSocket
write reply toserverSocketspecifying clienthost address,port umber
Client
Datagrammes UDP et Sockets
2 classes : DatagramPacket et DatagramSocket
Datagramme = un message indépendant envoyé sur le réseau arrivée, temps d’arrivée et contenu non garantis
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 demandeUn 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 socketun 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 paquetdatagramme au serveur indiquant qu’il souhaiterecevoir une citation et attend en réponse un paquetdu serveur.
La classe QuoteServer
socket = new DatagramSocket(4445);Création d’un DatagramSocket sur le port 4445 qui permet au serveurde communiquer avec tous ses 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 contientune liste de citations ( une citation par ligne)
suite
contient une boucle qui tant qu’il y a des citations dans le fichierattend 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 citationson 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 serveurif (args.length != 1) { System.out.println("Usage: java QuoteClient <hostname>"); return; }
La partie principale du main
Création d ’un DatagramSocketDatagramSocket 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
Avez-vous suivi ?
Quel est le protocole d’application pour le service de citation ?peut-on le changer ?
Quel est l’entrée du service sur la machine hôte ?peut-on la changer ?
Quelle est le marshalling associé au protocole d’application ?peut-on le changer ?
Quel est le protocole de transport ?peut-on le changer ?
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 sedé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…)
Petite comparaison UDP TCP
Services fournis par les protocoles de transport Internet
Service TCP : connection-oriented:
setup required between client, server
reliable transport between sending and receiving process
flow control: sender won’t overwhelm receiver
congestion control: throttle sender when network overloaded
does not providing: timing, minimum bandwidth guarantees
Service UDP : unreliable data transfer
between sending and receiving process
does not provide: connection setup, reliability, flow control, congestion control, timing, or bandwidth guarantee
Exigence de transport des applications communes
Time Sensitive
nononoyes, 100’s msec
yes, few secsyes, 100’s msecyes and no
Application
file transfere-mail
Web documentsreal-time audio/video
stored audio/videointeractive games
financial apps
Data loss
no lossno lossloss-tolerantloss-tolerant
loss-tolerantloss-tolerantno loss
Bandwidth
elasticelasticelasticaudio: 5Kb-1Mbvideo:10Kb-5Mbsame as above few Kbps upelastic
Protocoles Internet des applications et protocoles de transport associés
Application
e-mailremote terminal access
Web file transfer
streaming multimedia
remote file serverInternet telephony
Applicationlayer protocol
smtp [RFC 821]telnet [RFC 854]http [RFC 2068]ftp [RFC 959]proprietary(e.g. RealNetworks)NSFproprietary(e.g., Vocaltec)
Underlyingtransport protocol
TCPTCPTCPTCPTCP or UDP
TCP or UDPtypically UDP
Communication par diffusion : Multicast
Clientn
ServeurClient1
Client2
Gr
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)
Créer un paquet de sortiePréparer et Envoyer une donnée
Scénario d’un serveur
Fermer le socket d’entrée
Créer le socket d’entrée
Scénario d’un client
Création d’un paquet d’entréeAttente de données en entréeRéception et traitement des données en entrée
Fermer le socket d ’entrée
Créer 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 quele serveur « broadcast » à plusieurs clients. .
Une extension du QuoteServer : broadcaste à 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 à partirde données du client sur un MulticastSocket. Il aurait pu utiliser aussiun MulticastSocket. Le socket utilisé par le serveur pour envoyer leDatagramPacket n’est pas important. Ce qui est important pour lebroadcast 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 aServerSocketconnecté write read
read write
UDP aDatagramSocket aDatagramSocketnon connecté send receive
receive send
Multicast aMulticastSocket aDatagramSocket/aMulticastSocket
receive send
I/O Stream I/O Stream
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 objet 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 de la sé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 quiconstituent 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 afind’é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.
Définir un nouveau type de socket
Pourquoi ?Préparer les données avant de les envoyerReconstruire les données reçues
ExempleJava 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 relatives4 é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 relatives4 étapes
3. Etendre java.net.Socket Implémenter les constructeurs appropriés et surchargergetInputStream, getOutputStream et close.
4. Etendre java.net.ServerSocket Implémenter le constructeur et surcharger acceptpour 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èmes de bufferisation liés aux
E/S Charsets : qui associent des « décodeurs » et
des « encodeurs » qui gèrent correctement les conversions chaines – octets› Éliminent les problème d’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 communications UDP prises en charge par des sockets de type java.net.DatagramSocket
ServerSocketChannel : Un canal dédié aux connexions TCP prises en charge par des sockets de type java.net.ServerSocket
SocketChannel : Un canal dédié aux communications 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.
un canal est créé par appel à une méthode statique open définie dans chaque classe.
› La socket est créée par effet 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
….