Vous êtes sur la page 1sur 9

Programmation

client/serveur
java.net

© Philippe GENOUD UJF Décembre 2004 1

Communications
Communications sur
sur Internet
Internet

 Pour communiquer sur Internet les ordinateurs utilisent différents protocoles :

 TCP (Transfert Control Protocol) protocole destiné aux applications nécessitant


une communication fiable et robuste. Permet d’établir une connexion fiable
entre deux machines
 pas de perte d’information
 respect de l’ordre dans lequel les informations sont envoyées et reçues
 les applications sont prévenues si la communication est interrompue

 UDP (User Datagram Protocol) protocole qui permet l’envoi de paquets


indépendants (datagrammes) d’un ordinateur à un autre sans garantie quand à
leur arrivée
 plus rapide mais moins fiable

© Philippe GENOUD UJF Décembre 2004 2

1
Applications
Applications réseau
réseau Java
Java
Application Java Applications
java.net HTTP, ftp, telnet, …

Package standard qui permet aux Transport


programmes Java de réaliser des TCP, UDP, …
communications réseau de façon De nombreuses applications
indépendante du système Réseau se basent sur ces protocoles

IP, …

Couche de base
Object Device driver

Couche Physique
Ethernet, …
InetAdress

Socket ServerSocket

DatagramSocket DatagramPacket

URL URLConnection

© Philippe GENOUD UJF Décembre 2004 3

Sockets
Sockets et
et applications
applications Client/Serveur
Client/Serveur
1) Le programme serveur tourne sur une machine hôte spécifique
port

Serveur
Serveur Client
Client

Le programme serveur possède un « socket » associé


à un numéro de port spécifique
Le serveur est en attente d’une demande de connexion

2) Le client effectue une demande de connexion

Le client connaît la machine hôte


demande de (hostname ou numéro IP) et le
port

Serveur
Serveur connexion Client
Client numéro de port auquel est connecté
le serveur

3) Le serveur accepte la connexion


port

Client
Client
port

Serveur
Serveur
ion
ex

port Attribution d’un socket


nn

(et d’un numéro de port)


co

Attribution d’un nouveau socket (et 2 flots de données sont établis entre les deux machines :
d’un nouveau numéro de port) Le client et le serveur peuvent communiquer en écrivant ou en
lisant dans leur socket

© Philippe GENOUD UJF Décembre 2004 4

2
Sockets
Sockets TCP
TCP dans
dans java.net
java.net

 Assymétrie des connexions


 Deux classes pour les sockets en mode connecté (TCP)

 ServerSocket
 Encapsule le socket du serveur

 Pour s’initialiser un ServerSocket a besoin d’un numéro de port


 Attente et acceptation des demandes de connexion

 Socket
 Encapsule le socket du client

 Pour s’initialiser un Server a besoin d’une adresse IP et d’un


numéro de port
 Demande de connexion avec le serveur

© Philippe GENOUD UJF Décembre 2004 5

Client
Client // Serveur
Serveur avec
avec java.net
java.net :: principe
principe
(1) Le serveur
enregistre
son service
Serveur Le client doit être démarré après le serveur.
Si le serveur n’a pas encore démarré, levée
d’une exception après un time-out
ServerSocket svs =
(2) Le serveur se new ServerSocket(port#)
met en attente de Client (3) Etablir la
connexion connexion
svs.accept() Socket sc =
new Socket(host, port#)
Sortie de accept
retour d’un objet
Socket
(4) Utilisation
(4) Utilisation Socket s = du socket
du socket

InputStream OutputStream
socket Canal TCP socket
OutputStream InputStream
(5’) Fermer la
connexion (5) Fermer la
s.close() connexion
sc.close()
(6) Fermer le
sv.close()
service
close() ferme (détruit) le socket côté
client comme côté serveur

© Philippe GENOUD UJF Décembre 2004 6

3
Echanges
Echanges entre
entre client
client et
et serveur
serveur

 Pour échanger des données le serveur et le client utilisent les flux d’entrée/sortie
fournis par leur socket :
 Un objet java.io.InputStream pour la lecture retourné par la méthode
getInputStream() de Socket
 Un objet java.io.OutputStream pour l’écriture retourné par la méthode
getOutputStream() de Socket

 InputStream et OutputStream sont les classes du package java.io


proposant les primitives de base pour la lecture et l’écriture sur un flux d’entrée ou
de sortie

 Deux types d’échanges sont possibles


 Échanges en mode ligne (chaînes de caractères)
 Echanges en mode bloc d’octets (bytes)

© Philippe GENOUD UJF Décembre 2004 7

Echanges
Echanges en
en mode
mode ligne
ligne

 Requêtes et réponses sont constituées d’une ou plusieurs lignes de texte


(ASCII 7 bits, UTF-8, ISO-8859-1 (Latin-1) …)
 Exemple : HTTP, SMTP, …

 Utilisation des classes d’entrées/sorties du package java.io


 BufferedReader
 BufferedWriter

 Attention :
 Variation des terminateurs de ligne selon les OS
LF '\n' , CR '\r' , CRLF '\r' '\n'

 Encodage n’est pas supporté par tous les langages


 Certains protocoles (HTTP, SMTP …) limitent la longueur des lignes

© Philippe GENOUD UJF Décembre 2004 8

4
Echanges
Echanges en
en mode
mode ligne
ligne

 Le flux d’entrée

1) Obtention d’un flux (stream) d’entrée simple :


définit les opérations de base

2) Création d’un stream convertissant


InputStream in = maSocket.getInputStream();
les octets (bytes) reçus en char

InputStreamReader isReader = new InputStreamReader(in);

BufferedReader buffReader = new BufferedReader(isReader);

3) Création d’un stream de lecture avec


String line = buffReader.readLine(); tampon pour lire ligne par ligne dans
un stream de caractères

4) Lecture d’une ligne (chaîne de


caractères)

© Philippe GENOUD UJF Décembre 2004 9

Echanges
Echanges en
en mode
mode ligne
ligne

 Le flux de sortie

1) Obtention d’un flux (stream) de sortie simple :


définit les opérations de base

2) Création d’un stream convertissant


OutputStream out = maSocket.getOutputStream();
chaînes de caractères en octets (bytes)

PrintWriter writer = new PrintWriter(out);

writer.println(line); 3) Envoi d’une ligne (line est une String)

writer.flush();

4) Force l’envoi effectif sur le réseau


(force le « vidage » du buffer d’E/S)

© Philippe GENOUD UJF Décembre 2004 10

5
Echanges
Echanges en
en mode
mode bloc
bloc de
de données
données

 Les données échangées sont des blocs d’octets (bytes)


 Les blocs sont d’une taille et d’un format connus des deux partenaires
(le serveur et le client)
 un bloc peut avoir un entête qui contient un code d’opération et la
longueur des données (talle du bloc)
 Exemple : RPC (Remote Procedure Call), RMI (Remove Method
Invocation), …

 En Java, possibilité d’utiliser les classes


 java.io.DataInputStream
 java.io.DataOutputStream

© Philippe GENOUD UJF Décembre 2004 11

Protocole
Protocole d’échange
d’échange

 Un protocole d’échange spécifiant la structure des requêtes et réponses


échangées par le client et le serveur doit être fixé.

 Le client et le serveur doivent respecter ce protocole

 Exemples de problèmes possibles


 Format de données incorrect :

 le client envoie un entier alors que le serveur attend un flottant


 Interblocage :

 le client attend des données du serveur et le serveur attend des


données du client
 Hétérogénéité des plateformes client et serveur
 différence de codage des données sur le serveur et le client

© Philippe GENOUD UJF Décembre 2004 12

6
Classes
Classes d’exceptions
d’exceptions de
de java.net
java.net
C Coté client
 Principales classes d’exceptions de java.net S Coté serveur

java.lang.Exception
C S
Erreur du protocole TCP/IP
(problème de configuration
Problème générique de java.io.IOException De la pile TCP/IP)
connexion)
C S

SocketException ProtocolException

UnknownHostException
ConnectException

BindException C Erreur du DNS : L’adresse


IP de l’hôte ne peut être
déterminée
NoRouteToHostException
L’hôte n’est pas joignable.
C Refus de connexion par
S
Un service est Le routeur ne trouve pas le
l’hôte (aucun service déjà associé à
associé au numéro de port) ce numéro de C serveur ou le serveur est
protégé par un firewall
port

© Philippe GENOUD UJF Décembre 2004 13

Servir
Servir plusieurs
plusieurs clients
clients
Ne permet de servir qu’un
ServeurSocket sSock = new ServeurSocket(4444); seul client
Socket s = sSock.accept();
// création d’une socket quand un demande de connexion a été acceptée

// traiter le client associé à cette connexion


 Si plusieurs demandes de connexion arrivent simultanément, une seule est


acceptée, les autres sont mises en attente jusqu’au accept suivant (modulo
les time-out)
ServeurSocket sSock = new ServeurSocket(4444);
boolean arretServeur = false; Sert plusieurs clients
MAIS consécutivement
while (! arretServeur) {

Socket s = sSock.accept();
// création d’une socket quand un demande de connexion a été acceptée

// traiter le client associé à cette connexion


 Pour accepter et traiter plusieurs connexions simultanées, il faut multithreader le serveur

© Philippe GENOUD UJF Décembre 2004 14

7
Serveur
Serveur Multithreadé
Multithreadé
ServeurSocket sSock = new ServeurSocket(4444);
boolean arretServeur = false;

while (! arretServeur) {

Socket s = sSock.accept();

 // création d’une socket quand un demande de connexion a été acceptée

// traiter le client associé à cette connexion



 Créer et Lancer un thread pour traiter ce client
}

Thread dispatcher
Attente demande
 de connexion

Récupération de la socket
 Dédiée à la connexion Thread de service Client 1
Création et lancement
 d’un thread de service Prise en
Prise en charge du
Prise en charge
du
charge du
dialogue
dialogue avec le client 1
dialogue avec
avec le
le client
client 1
1
Attente demande
 de connexion

Récupération de la socket
 Dédiée à la connexion
Thread de service Client 2
Création et lancement
 d’un thread de service
Prise
Prise en
dialogue
en charge
charge du
dialogue avec
avec le
du
le client
client
Attente demande
 de connexion

© Philippe GENOUD UJF Décembre 2004 15

Serveur
Serveur Multithreadé
Multithreadé
...
ServeurSocket sSock = new ServeurSocket(4444);
boolean arretServeur = false;

while (! arretServeur) {

Socket sock = sSock.accept();


// création d’une socket quand un demande de connexion a été acceptée

// traiter le client associé à cette connexion


// créer un thread pour traiter le client

ServiceClient sc = new ServiceClient(sock);
Thread threadService = new Thread(sc);
threadService.start();

...

<interface> ServiceClient
Runnable
+ ServiceClient(Socket s)
+ run()
+ run()
Le traitement du
client

© Philippe GENOUD UJF Décembre 2004 16

8
Client
Client Multitread
Multitread
public class ServiceClient implements Runnable {
private Socket s;
private BufferedReader in;
private PrintWriter out;
private boolean termine = false;
... Création des flux
d’entrée/sortie
public ServiceClient(Socket s) {
pour communiquer
this.s = s;
in = new BufferedReader( avec le serveur
new InputStreamReader((s.getInputStream()));
out = new PrintWriter(s.getOutputStream());
...
}

public void run() { Le traitement du


try { client
while (! termine) {
String line = in.readLine();
...
Une gestion plus fine des
out.println(...);
exceptions est possible
}
} Quel que soit le cas de figure
catch (IOException ioe) { ... } on essaye de fermer le
finally { socket avant de terminer le
try { s.close(); } catch (IOException ioe) { ... } traitement du client
}
}

...
}
© Philippe GENOUD UJF Décembre 2004 17

Exercice
Exercice

 (1) Ecrire une application client serveur minimale


 Le client lit une chaîne au clavier qu’il envoie vers le serveur

 Le serveur affiche la chaîne lue et renvoie un accusé de


réception au client qui l’affiche
 Pour terminer sa session le client envoie la chaîne « fin »

 (2) Modifier le programme de façon à avoir plusieurs clients

© Philippe GENOUD UJF Décembre 2004 18