Les Sockets et Java
Cours réseaux Essi2
Anne-Marie Déry
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)
Architecture client serveur
Mode de communication qu’un hôte établit avec un autre hôte
qui fournit un service quelconque
application
opération
Client
Serveur
Send request
Send reply
« protocole d’application »
Exemples d ’applications
Classiques
Serveur de Messages
Serveur de news Sockets
Serveur de fichiers
Applications distribuées RMI
Réservation de voyages
Serveurs de vente
Composants distribués…. EJBs
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) : 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
ypcat hosts sur SUN
157.169.9.15 oscar.essi.fr oscar
157.169.20.5 accueil.essi.fr accueil
157.169.20.4 compta.essi.fr compta
157.169.25.201 www-local.essi.fr www-local
157.169.10.222 pcprofs.essi.fr pcprofs
157.169.4.50 ada.essi.fr ada
157.169.10.120 macserver.essi.fr macserver
157.169.10.240 demo.essi.fr demo
157.169.1.20 bibli.essi.fr bibli
157.169.25.110 sfe-srv.essi.fr sfe-srv sfe
157.169.1.153 bde.essi.fr bde
157.169.3.204 niv1a.essi.fr niv1a
157.169.1.155 dessi.essi.fr dessi
157.169.10.2 jessica.essi.fr jessica print2
Exemples d ’adresses
157.169.25.200 news-srv.essi.fr news-srv www.essi.fr
www-srv.essi.fr news
134.59.132.21 dolphin.unice.fr
157.169.10.1 essi2.essi.fr loghost essi2
Essi : 157.169
I3S: 134.59
serveurs : 25
Administration : 1
…….
Ports réservés
TCP
Serveur FTP : 21
Serveur Telnet : 23
Serveur SMTP : 25
UDP
Agent SNMP : 161
Logger SNMP : 162
Serveur rwhod : 513
Serveur multi processus Applications transactionnelles
1 à 1024 services fondamentaux (administrateurs)
(sous unix cf. le fichier /etc/services)
1025 à 5000 disponibles pour les utilisateurs
Plus précisément un socket
Plusieurs types de sockets :
pour la communication inter processus classique
pour communication réseau en mode datagramme
pour communication réseau en mode connecté
une machine joue le rôle du serveur et une autre
(ou plusieurs) pour le client
Scénario d’un serveur
Création d ’un paquet d ’entrée
Attente de données en entrée
Réception des données en entrée et
calcul
Création d’un paquet de sortie
Envoi de la réponse
Fermer le socket d ’entrée
Créer le socket d ’entrée
Scénario d’un client
Créer un paquet de sortie
Envoyer une requête
Créer un paquet d ’entrée
Attendre des données en entrée
Recevoir les données et les traiter
Fermer le socket d ’entrée
Créer le socket d ’entrée
Sockets (Communication Client
serveur)
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 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
Serveurs actifs
Activation manuelle peu recommandée
Utilisation de Inetd sous UNIX
Serveur particulier (démon) attend pour les
autres
serveurs
fichier de configuration : /etc/inetd.conf
fichier /etc/services
Contexte : modèle OSI
Couches Transports : Transmission Control Protocol
User Datagram Protocol
Couche communication : Internet Protocol
Mode connecté vs mode non connecté
rester en ligne pour demander plusieurs services ou
rappeler l’entreprise pour chaque nouvelle requête
Sockets en Java ?
BSD sockets UNIX
au dessus de TCP ou UDP
En Java toutes les classes relatives aux sockets
sont dans le package java.net
Une infrastructure puissante et
flexible 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
HttpAwareServerSocket
DatagramSocke
t
MulticastSocket
Socket
HttpSendSocket WrappedSocket
Object
Des exceptions
Exception
IOException
SocketException ProtocolException
UnknownHostException UnknownServiceException
BindException ConnectException
Des Entrées Sorties
Object
InputStream
FileInputStream
SocketInputStream
OutputStream
FileOutputStream
SocketOutputStream
Autres Classes
Object
InetAdress DatagramPacket SocketImpl
PlainSocketImpl
Programmation en Java
 Les opérations de base
 Un exemple : le service SMTP
 Un serveur d’Echo
 Aperçus des autres types de communication
– Plusieurs Clients gérés simultanément ( ligne non
occupée)
– Client Serveur dataGram
– Communication Broadcast (réunion téléphonique)
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)
…..
TCP et Sockets
2 classes : Socket et ServerSocket (java.net package)
Flot de requêtes du client vers le
serveur
application
opération
Client
Serveur
Ouvrir connexion
req1
req2
req3
reqn
Fermer la connexion
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
...
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
...
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
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)
Dans un serveur ?
ServerSocket MyService;
try {
MyServerice = new ServerSocket(PortNumber);
}
catch (IOException e) {System.out.println(e);}
Création d’un objet socket pour écouter et accepter les
connexions des clients
Socket clientSocket = null;
try { ServiceSocket = MyService.accept();}
catch (IOException e) {System.out.println(e); }
Comment créer un Input
Stream ?
Côté client : pour recevoir une réponse du serveur
try {input = new DataInputStream(MyClient.getInputStream());}
catch (IOException e) {System.out.println(e);}
DataInputStream : lire des lignes de texte, des entiers, des
doubles,des caractères...
( read, readChar, readInt, readDouble, and readLine,. )
Côté Serveur
pour recevoir les données d’un client
DataInputStream input;:
try {
input = new DataInputStream(serviceSocket.getInputStream());
}
catch (IOException e) {System.out.println(e);}
Comment créer un Output
Stream?
Côté client : pour envoyer une information au serveur
(PrintStream ou DataOutputStream)
PrintStream output;
try {output = new PrintStream(MyClient.getOutputStream;}
catch (IOException e) {System.out.println(e);}
PrintStream pour afficher des valeurs des types de base
(write et println)
…..
Côté Serveur
Pour envoyer des informations au client
PrintStream output;
try {
output = new PrintStream(serviceSocket.getOutputStream());
}
catch (IOException e) {System.out.println(e);}
DataOutputStream : écrire des types de données primitifs;
(writeBytes…)
output=
new DataOutputStream(serviceSocket.getOutputStream());
Autres entrées sorties
echoSocket = new Socket( "jessica", 7);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
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();
serviceSocket.close();
MyService.close();
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("HELOn");
os.writeBytes("MAIL From: pinna@essi.frn");
os.writeBytes("RCPT To: pinna@essi.frn");
os.writeBytes("DATAn");
os.writeBytes("From: pinna@essi.frn");
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);}
} } }
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);}
} }
Plusieurs clients
application
Clientn
Serveur
Ouvrir connexion
application
Client1
application
Client2 S1
S2
Sn
Plusieurs Clients
Utiliser des threads pour accepter plusieurs clients
simultanément.
Le serveur gère un thread par client
Thread constructeur
start
run
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.
Un thread qui calcule des primes
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeThread p = new PrimeThread(143);
p.start();
Version2
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
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 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
Envoi de datagrammes
application
opération
Client
Serveur
req1
rep1
reqn
repn
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…)
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
import java.io.*;
public class QuoteServer {
public static void main(String[] args) throws IOException {
new QuoteServerThread().start();
}
}
la classe QuoteServerThread implémente toute la logique du serveur.
La classe QuoteServerThread
public QuoteServerThread() throws IOException {
this("QuoteServer");
}
public QuoteServerThread(String name) throws IOException {
super(name);
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)
La méthode RUN
implémentation du thread
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
Multicasr
application
Clientn
Serveur
application
Client1
application
Client2
Gr
Exemple de multicast
Un serveur de citation qui envoie une citation toutes les minutes
à tous les clients qui écoutent (multicast)
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)
Broadcast: 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
Le serveur a un nouveau nom et crée un MulticastServerThread
qui contient le cœur du serveur.
import java.io.*;
public class MulticastServer {
public static void main(String[] args) throws IOException {
new MulticastServerThread().start();
}
}
public class MulticastServerThread extends QuoteServerThread {
...
}
utilisation du constructeur par héritage
et héritage de variables et de la méthode getNextQuote
Une nouvelle méthode RUN
public void run() {
while (moreQuotes) {
try { byte[] buf new byte[256];
// don't wait for request...just send a quote
String dString = null;
if (in == null) dString = new Date().toString();
else dString = getNextQuote();
buf = dString.getBytes();
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet;
packet = new DatagramPacket(buf, buf.length, group, 4446);
socket.send(packet);
try {sleep((long)Math.random() * FIVE_SECONDS);
} catch (InterruptedException e) { }
} catch (IOException e) { e.printStackTrace();
moreQuotes = false;}
} socket.close();}
Différences principales
Le DatagramPacket est construit à partir de
de « l’adresse de plusieurs clients »
L ’adresse et le no de port sont câblés
no de port 4446 (tout client doit avoir un MulticastSocket lié à ce no).
L’adresse InetAddress "230.0.0.1" correspond à un identificateur de
groupe et non à une adresse Internet de la machine d’un client
Le DatagramPacket est destiné à tous les clients qui écoutent le port 4446
et qui sont membres du groupe "230.0.0.1".
Un nouveau Client
Pour écouter le port 4446, le programme du client doit créer son
MulticastSocket avec ce no.
Pour être membre du groupe "230.0.0.1" le client adresse la méthode
joinGroup du MulticastSocket avec l’adresse d’identification du groupe.
Le serveur utilise un DatagramSocket pour faire du broadcast à partir
de données du client sur un MulticastSocket. Il aurait pu utiliser aussi
un MulticastSocket. Le socket utilisé par le serveur pour envoyer le
DatagramPacket n’est pas important. Ce qui est important pour le
broadcast est d’adresser l’information contenue dans le DatagramPacket,
et le socket utilisé par le client pour l’écouter.
MulticastSocket socket = new MulticastSocket(4446);
InetAddress group = InetAddress.getByName("230.0.0.1");
socket.joinGroup(group);
DatagramPacket packet;
for (int i = 0; i < 5; i++) {
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData());
System.out.println("Quote of the Moment: " + received);
}
socket.leaveGroup(group);
socket.close();
Synthèse
Client Serveur
TCP aSocket aServerSocket
connecté write read
read write
UDP aDatagramSocket aDatagramSocket
non connecté send receive
receive send
Broadcast aMulticastSocket aDatagramSocket/
aMulticastSocket
receive send
I/O Stream I/O Stream
aDatagramPacket
Définir un nouveau type de
socket
Pourquoi ?
Préparer les données avant de les envoyer
Préparer les données reçues
Exemple
Java RMI
Sockets spécialisées (marshalling et unmarshalling)
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
1. Etendre java.io.FilterOutputStream
pour créer un output stream pour ce type de Socket.
Surcharge de méthodes si nécessaire.
2. Etendre java.io.FilterInputStream
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.
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
et maintenant les EJB : Entreprise Java Beans
et JINI …..

coursSocketJava.ppt cours programmation OO

  • 1.
    Les Sockets etJava Cours réseaux Essi2 Anne-Marie Déry
  • 2.
    Sockets ? Outil decommunication 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)
  • 3.
    Architecture client serveur Modede communication qu’un hôte établit avec un autre hôte qui fournit un service quelconque application opération Client Serveur Send request Send reply « protocole d’application »
  • 4.
    Exemples d ’applications Classiques Serveurde Messages Serveur de news Sockets Serveur de fichiers Applications distribuées RMI Réservation de voyages Serveurs de vente Composants distribués…. EJBs
  • 5.
    Besoins d’une applicationClient- 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 ?
  • 6.
    Un peu devocabulaire 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) : correspondances entre noms logiques et adresses IP (Annuaire) Port : canal dédié à un service Protocole :langage utilisé par 2 ordinateurs pour communiquer entre eux
  • 7.
    Adresse Internet etPort 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
  • 8.
    Exemples d ’adressesInternet ypcat hosts sur SUN 157.169.9.15 oscar.essi.fr oscar 157.169.20.5 accueil.essi.fr accueil 157.169.20.4 compta.essi.fr compta 157.169.25.201 www-local.essi.fr www-local 157.169.10.222 pcprofs.essi.fr pcprofs 157.169.4.50 ada.essi.fr ada 157.169.10.120 macserver.essi.fr macserver 157.169.10.240 demo.essi.fr demo 157.169.1.20 bibli.essi.fr bibli 157.169.25.110 sfe-srv.essi.fr sfe-srv sfe 157.169.1.153 bde.essi.fr bde 157.169.3.204 niv1a.essi.fr niv1a 157.169.1.155 dessi.essi.fr dessi 157.169.10.2 jessica.essi.fr jessica print2
  • 9.
    Exemples d ’adresses 157.169.25.200news-srv.essi.fr news-srv www.essi.fr www-srv.essi.fr news 134.59.132.21 dolphin.unice.fr 157.169.10.1 essi2.essi.fr loghost essi2 Essi : 157.169 I3S: 134.59 serveurs : 25 Administration : 1 …….
  • 10.
    Ports réservés TCP Serveur FTP: 21 Serveur Telnet : 23 Serveur SMTP : 25 UDP Agent SNMP : 161 Logger SNMP : 162 Serveur rwhod : 513 Serveur multi processus Applications transactionnelles 1 à 1024 services fondamentaux (administrateurs) (sous unix cf. le fichier /etc/services) 1025 à 5000 disponibles pour les utilisateurs
  • 11.
    Plus précisément unsocket Plusieurs types de sockets : pour la communication inter processus classique pour communication réseau en mode datagramme pour communication réseau en mode connecté une machine joue le rôle du serveur et une autre (ou plusieurs) pour le client
  • 12.
    Scénario d’un serveur Créationd ’un paquet d ’entrée Attente de données en entrée Réception des données en entrée et calcul Création d’un paquet de sortie Envoi de la réponse Fermer le socket d ’entrée Créer le socket d ’entrée
  • 13.
    Scénario d’un client Créerun paquet de sortie Envoyer une requête Créer un paquet d ’entrée Attendre des données en entrée Recevoir les données et les traiter Fermer le socket d ’entrée Créer le socket d ’entrée
  • 14.
    Sockets (Communication Client serveur) Serveurconnecte 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 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
  • 15.
    Serveurs actifs Activation manuellepeu recommandée Utilisation de Inetd sous UNIX Serveur particulier (démon) attend pour les autres serveurs fichier de configuration : /etc/inetd.conf fichier /etc/services
  • 16.
    Contexte : modèleOSI Couches Transports : Transmission Control Protocol User Datagram Protocol Couche communication : Internet Protocol Mode connecté vs mode non connecté rester en ligne pour demander plusieurs services ou rappeler l’entreprise pour chaque nouvelle requête
  • 17.
    Sockets en Java? BSD sockets UNIX au dessus de TCP ou UDP En Java toutes les classes relatives aux sockets sont dans le package java.net Une infrastructure puissante et flexible pour la programmation réseau
  • 18.
    Le Package net Des Exceptions  Des entrées Sorties  Des Sockets  …... Plusieurs hiérarchies de classes
  • 19.
    Des types deSockets ServerSocket HttpAwareServerSocket DatagramSocke t MulticastSocket Socket HttpSendSocket WrappedSocket Object
  • 20.
  • 21.
  • 22.
  • 23.
    Programmation en Java Les opérations de base  Un exemple : le service SMTP  Un serveur d’Echo  Aperçus des autres types de communication – Plusieurs Clients gérés simultanément ( ligne non occupée) – Client Serveur dataGram – Communication Broadcast (réunion téléphonique)
  • 24.
    Java.net.InetAddress : nommage Laclasse 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) …..
  • 25.
    TCP et Sockets 2classes : Socket et ServerSocket (java.net package)
  • 26.
    Flot de requêtesdu client vers le serveur application opération Client Serveur Ouvrir connexion req1 req2 req3 reqn Fermer la connexion
  • 27.
    TCP et Sockets Laclasse 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 ...
  • 28.
    TCP et Sockets Laclasse 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 ...
  • 29.
    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
  • 30.
    Comment ouvrir unsocket ? 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)
  • 31.
    Dans un serveur? ServerSocket MyService; try { MyServerice = new ServerSocket(PortNumber); } catch (IOException e) {System.out.println(e);} Création d’un objet socket pour écouter et accepter les connexions des clients Socket clientSocket = null; try { ServiceSocket = MyService.accept();} catch (IOException e) {System.out.println(e); }
  • 32.
    Comment créer unInput Stream ? Côté client : pour recevoir une réponse du serveur try {input = new DataInputStream(MyClient.getInputStream());} catch (IOException e) {System.out.println(e);} DataInputStream : lire des lignes de texte, des entiers, des doubles,des caractères... ( read, readChar, readInt, readDouble, and readLine,. )
  • 33.
    Côté Serveur pour recevoirles données d’un client DataInputStream input;: try { input = new DataInputStream(serviceSocket.getInputStream()); } catch (IOException e) {System.out.println(e);}
  • 34.
    Comment créer unOutput Stream? Côté client : pour envoyer une information au serveur (PrintStream ou DataOutputStream) PrintStream output; try {output = new PrintStream(MyClient.getOutputStream;} catch (IOException e) {System.out.println(e);} PrintStream pour afficher des valeurs des types de base (write et println) …..
  • 35.
    Côté Serveur Pour envoyerdes informations au client PrintStream output; try { output = new PrintStream(serviceSocket.getOutputStream()); } catch (IOException e) {System.out.println(e);} DataOutputStream : écrire des types de données primitifs; (writeBytes…) output= new DataOutputStream(serviceSocket.getOutputStream());
  • 36.
    Autres entrées sorties echoSocket= new Socket( "jessica", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream()));
  • 37.
    Comment fermer unsocket ? 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(); serviceSocket.close(); MyService.close();
  • 38.
    Comment écrire unclient ? 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é
  • 39.
    Client SMTP (SimpleMail 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"); }
  • 40.
    Le protocole SMTP,RFC1822/3 if (smtpSocket != null && os != null && is != null) { try{os.writeBytes("HELOn"); os.writeBytes("MAIL From: pinna@essi.frn"); os.writeBytes("RCPT To: pinna@essi.frn"); os.writeBytes("DATAn"); os.writeBytes("From: pinna@essi.frn"); os.writeBytes("Subject: Qui est là ?n"); os.writeBytes("Vous suivez toujours ?n"); // message os.writeBytes("n.n"); os.writeBytes("QUIT");
  • 41.
    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);} } } }
  • 42.
    Serveur Echo Un serveursimilaire à echo ( port 7). Reçoit un texte du client et le renvoie identique Le serveur gère un seul client.
  • 43.
    Déclarations import java.io.*; importjava.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); }
  • 44.
    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);} } }
  • 45.
  • 46.
    Plusieurs Clients Utiliser desthreads pour accepter plusieurs clients simultanément. Le serveur gère un thread par client Thread constructeur start run
  • 47.
    Quelques mots surles 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.
  • 48.
    Un thread quicalcule des primes class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeThread p = new PrimeThread(143); p.start();
  • 49.
    Version2 class PrimeRun implementsRunnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeRun p = new PrimeRun(143); new Thread(p).start();
  • 50.
    Datagrammes UDP etSockets 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
  • 51.
    Exemple Un serveur decitation 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
  • 52.
  • 53.
    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)
  • 54.
    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…)
  • 55.
    Une Application ClientServeur 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.
  • 56.
    La classe QuoteServer importjava.io.*; public class QuoteServer { public static void main(String[] args) throws IOException { new QuoteServerThread().start(); } } la classe QuoteServerThread implémente toute la logique du serveur.
  • 57.
    La classe QuoteServerThread publicQuoteServerThread() throws IOException { this("QuoteServer"); } public QuoteServerThread(String name) throws IOException { super(name); 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)
  • 58.
    La méthode RUN implémentationdu thread 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);
  • 59.
    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();
  • 60.
    La classe QuoteClient envoieune 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; }
  • 61.
    La partie principaledu 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
  • 62.
  • 63.
    Exemple de multicast Unserveur de citation qui envoie une citation toutes les minutes à tous les clients qui écoutent (multicast)
  • 64.
    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)
  • 65.
    Broadcast: MulticastSocket Type desocket 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 Le serveur a un nouveau nom et crée un MulticastServerThread qui contient le cœur du serveur. import java.io.*; public class MulticastServer { public static void main(String[] args) throws IOException { new MulticastServerThread().start(); } }
  • 66.
    public class MulticastServerThreadextends QuoteServerThread { ... } utilisation du constructeur par héritage et héritage de variables et de la méthode getNextQuote
  • 67.
    Une nouvelle méthodeRUN public void run() { 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();}
  • 68.
    Différences principales Le DatagramPacketest 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".
  • 69.
    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.
  • 70.
    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();
  • 71.
    Synthèse Client Serveur TCP aSocketaServerSocket connecté write read read write UDP aDatagramSocket aDatagramSocket non connecté send receive receive send Broadcast aMulticastSocket aDatagramSocket/ aMulticastSocket receive send I/O Stream I/O Stream aDatagramPacket
  • 72.
    Définir un nouveautype de socket Pourquoi ? Préparer les données avant de les envoyer Préparer les données reçues Exemple Java RMI Sockets spécialisées (marshalling et unmarshalling) Images : Compression et Décompression Comment ? En spécialisant les classes de base
  • 73.
    Comment Définir unnouveau type de Sockets La classe CompressionSocket et ses classes relatives 4 étapes 1. Etendre java.io.FilterOutputStream pour créer un output stream pour ce type de Socket. Surcharge de méthodes si nécessaire. 2. Etendre java.io.FilterInputStream 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.
  • 74.
    Conclusion Une large bibliothèquepour 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 et maintenant les EJB : Entreprise Java Beans et JINI …..