Introduction Aux Sockets
Introduction Aux Sockets
Introduction Aux Sockets
sockets
Par SoftDeath
www.siteduzero.com
Sommaire
Sommaire ........................................................................................................................................... 2
Lire aussi ............................................................................................................................................ 1
Introduction aux sockets .................................................................................................................... 3
Récupérer une adresse IP avec InetAddress ................................................................................................................... 4
Qu'est-ce qu'un socket ? ................................................................................................................................................... 5
Échange de message ....................................................................................................................................................... 8
Côté Serveur ............................................................................................................................................................................................................. 11
Côté Client ................................................................................................................................................................................................................. 11
Utilisation des threads ............................................................................................................................................................................................... 11
TP : un mini-chat entre le client et le serveur ! ................................................................................................................ 13
Q.C.M. ............................................................................................................................................................................. 22
Partager ..................................................................................................................................................................................................................... 23
www.siteduzero.com
Sommaire 3/24
Par SoftDeath
Mise à jour : 15/05/2012
Difficulté : Difficile
Avant de vous lancer dans la lecture de ce tutoriel, les deux premières parties de cysboy sur le langage Java ainsi que la
lecture de celui sur les threads et les flux d'entrées et sorties (1/2) sont primordiales pour bien suivre le cours !
Je vous recommande également de lire le chapitre de Dalshim Bien fermer ses threads en Java si vous voulez bien maîtriser la
fermeture de vos threads.
Les sockets servent à communiquer entre deux hôtes appelés Client / Serveur à l'aide d'une adresse IP et d'un port que j'appelle
prise ; ces sockets permettront de gérer des flux entrant et sortant afin d'assurer une communication entre les deux (le client et le
serveur), soit de manière fiable à l'aide du protocole TCP/IP, soit non fiable mais plus rapide avec le protocole UDP. Nous allons
étudier le premier mode, le mode TCP/IP…
Les sockets sont utilisés dans plusieurs autres langages, tels que :
Lire les parties « histoire » et « définitions » de tutoriels ci-dessus ne vous fera pas de mal.
Ne tardons pas et commençons.
Sommaire du tutoriel :
www.siteduzero.com
Introduction aux sockets 4/24
getHostName() : elle retourne le nom de la machine dont l'adresse est stockée dans l'objet.
getAddress() : elle retourne l'adresse IP stockée dans l'objet sous forme d'un tableau de 4 octets.
toString() : elle retourne un String qui correspond au nom de la machine et son adresse.
Code : Java
import java.net.InetAddress;
import java.net.UnknownHostException;
InetAddress LocaleAdresse ;
InetAddress ServeurAdresse;
try {
LocaleAdresse = InetAddress.getLocalHost();
System.out.println("L'adresse locale est : "+LocaleAdresse );
ServeurAdresse= InetAddress.getByName("www.siteduzero.com");
System.out.println("L'adresse du serveur du
site du zéro est : "+ServeurAdresse);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
Et le résultat est :
Code : Console
www.siteduzero.com
Introduction aux sockets 5/24
Fastoche, hein ?
La classe InetAdress peut lever une exception de type UnknownHostException, tâchez de ne pas l'oublier !
Nous savons maintenant comment récupérer l'adresse IP de notre machine ou d'une machine distante, que diriez-vous si l'on
l'utilisait pour créer notre tout premier socket ? C'est parti
Un serveur fonctionne sur une machine bien définie et est lié à un numéro de port spécifique. Le serveur se met simplement à
l'écoute d'un client, qui demande une connexion.
En outre, java.net comprend la classe ServerSocket, qui met en oeuvre une sorte de prise que les serveurs peuvent utiliser pour
écouter et accepter les connexions des clients. Ce qui nous donne :
Code : Java
Ainsi on obtient un objet de la classe ServerSocket sur un port spécifique : si ce dernier est à 0, le socket est créée sur n'importe
quel port libre.
Il existe deux autres constructeurs ; l'un a deux paramètres, le premier est bien sûr le numéro de port et le nombre total de
connexion simultanées acceptées, voyez :
Code : Java
nbr_max est le nombre maximal de connexions traitées simultanément. Par exemple au-delà de cinq tentatives de connexion
consécutives autorisées, les connexions sont refusés.
www.siteduzero.com
Introduction aux sockets 6/24
Code : Java
Quant au client, celui-ci connaît le nom de la machine sur laquelle le serveur est en exécution et le numéro de port sur lequel il
écoute. Le client va demander une connexion au serveur en s'identifiant avec son adresse IP ainsi que le numéro de port qui lui
est lié.
Pour cela, le package java.net fournit une classe Socket qui met en œuvre une connexion bidirectionnelle entre votre programme
Java et un autre programme situé sur le réseau. La classe Socket permet de cacher les détails d'implémentation de cette
connexion. En utilisant cette classe en lieu et place d'un code natif, vos programmes peuvent communiquer sur le réseau quel
que soit la plateforme sur laquelle ils se trouvent. La création d'un socket pour un programme client s'effectue à l'aide d'un des
constructeurs suivants :
Code : Java
Le premier paramètre correspond à l'identité du client, il peut être une chaine de caractère ou de type InetAddress, param2
correspond au numéro de port sur lequel on souhaite se connecter sur le serveur. Il est possible également de spécifier son
adresse local comme troisième paramètre et le numéro de port local :
Code : Java
Après tentative de connexion, si tout va bien, le serveur accepte la connexion du client, et reçoit un nouveau socket qui est
directement lié au même port local. Il a besoin d'une nouvelle prise de sorte qu'elle puisse continuer à écouter le socket d'origine
pour les demandes de connexion, tout t'en satisfaisant les besoins du client connecté. Voici comment accepter une connexion
d'un client :
Code : Java
Une fois le socket créé, l'attente de connexion provenant du client se fait à l'aide de la méthode accept().
La méthode accept() reste bloquante tant qu'elle n'a pas détecté de connexion.
Afin d'éviter une attente infinie, il est possible de spécifier un délai maximal d'attente à l'aide d'un mutateur setSoTimeout.
Si un timeout est une valeur strictement positive, l'appel accept() va générer une attente maximale égale à timeout. Si ce temps
expire, une exception de type InterruptedIOException est levée sans toute fois que la socket de type ServerSocket ne soit
invalidée. La lecture de ce timeout se fait à l'aide de l'accesseur getSoTimeout().
Côté client, si la connexion est acceptée, une socket est créé et le client peut utiliser la socket pour communiquer avec le serveur.
www.siteduzero.com
Introduction aux sockets 7/24
On va essayer d'établir une communication. Vous avez tout les éléments à portée de main, vous pouvez désormais établir une
connexion, au boulot !
Serveur.java
Code : Java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
ServerSocket socketserver ;
Socket socketduserveur ;
try {
}catch (IOException e) {
e.printStackTrace();
}
}
Client.java
Code : Java
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
Socket socket;
try {
}catch (UnknownHostException e) {
www.siteduzero.com
Introduction aux sockets 8/24
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
Vous venez d'établir votre première connexion entre un serveur et un client . Maintenant, voyons comment envoyer et
recevoir des messages.
Attention : il ne faut jamais oublier de fermer le socket ! Sinon si vous utilisez le même port dans un autre programme, ce
(l'action de fermer une socket) ne sera plus possible car il (le port) sera occupé !
Échange de message
Une fois la connexion établie et les sockets en possession, il est possible de récupérer le flux d'entrée et de sortie de la connexion
TCP vers le serveur. Il existe deux méthodes pour permettre la récupération des flux :
getInputStream() de la classe InputStream. Elle nous permet de gérer les flux entrant ;
getOutputStream() de la classe OuputStream. Elle nous permet de gérer les flux sortant.
Ces deux méthodes nous permettent donc de gérer les flux en entrée et en sortie. En général le type d'entrée et sortie utilisé est
BufferedReader et InputStreamReader pour la lecture, PrintWriter pour l'écriture. Mais on peut utiliser tous les autres flux.
BufferedReader : cette classe permet de lire des caractères à partir d'un flux tamponné, afin de faire des lectures plus
rapides ;
InputStreamReader : convertit un flux binaire en flux de caractères : elle convertit un objet de type InputStream en objet
de type Reader ;
PrintWriter : la classe PrintWriter ajoute à un flux la possibilité de faire des écritures sous forme de texte des types
primitifs Java, et des chaînes de caractères.
www.siteduzero.com
Introduction aux sockets 9/24
Serveur.java
Code : Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.io.PrintWriter;
ServerSocket socketserver ;
Socket socketduserveur ;
BufferedReader in;
PrintWriter out;
try {
socketduserveur.close();
socketserver.close();
}catch (IOException e) {
www.siteduzero.com
Introduction aux sockets 10/24
e.printStackTrace();
}
}
Client.java
Code : Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
Socket socket;
BufferedReader in;
PrintWriter out;
try {
socket.close();
}catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
www.siteduzero.com
Introduction aux sockets 11/24
Code : Console
Demande de connexion
Vous êtes connecté zéro !
Côté Serveur
Après établissement de la connexion, le serveur obtient son socket qu'il utilise pour gérer le flux sortant à l'aide de
socketduserveur.getOutputStream() ; ensuite, à l'aide de la méthode println on envoie un message au client, on utilise flush
pour vider le buffer tout simplement. Et pour finir on ferme la connexion.
Côté Client
Après avoir obtenu notre socket, on utilise socket.getInputStream() pour récupérer le flux sortant. La méthode readLine() nous
permet de lire une chaîne de caractères. Il existe plusieurs autres méthodes telles :
Ça a l'air très simple à première vue pour deux hôtes, mais si l'on veut que plus que deux puissent communiquer entre eux à la
fois, comment faire ? D'où la nécessité d'utiliser les Threads.
Je pars du principe que vous connaissez ce que sont les threads et comment les utiliser et pourquoi doit-on les utiliser dans nos
programme, on va donc attaquer directement la pratique.
Le principe d'utilisation des Threads est simple (sera simple si vous suivez attentivement :D). Après avoir créer un objet
ServerSocket par le serveur, on le place (l'objet) comme paramètre à un constructeur de la classe qui implémente la classe
Runnable ou étend la classe Thread , dès qu'un client souhaite se connecter avec le serveur, un Thread s'occupe de la
connexion, il ne sera plus la peine de faire appel au serveur lorsqu'un client souhaite se connecter, tout le boulot sera confié à un
Thread.
Vous commencez à comprendre l'utilité des Threads avec le temps vous ne pourrez plus vous en passer.
Voyons un petit exemple de connexion Multi-Threads en image et avec un code source toujours :
www.siteduzero.com
Introduction aux sockets 12/24
Serveur.java
Code : Java
import java.io.IOException;
import java.net.*;
ServerSocket socket;
try {
socket = new ServerSocket(2009);
Thread t = new Thread(new Accepter_clients(socket));
t.start();
System.out.println("Mes employeurs sont prêts !");
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
while(true){
socket = socketserver.accept(); // Un client se connecte on
l'accepte
System.out.println("Le client numéro "+nbrclient+
" est connecté !");
nbrclient++;
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
www.siteduzero.com
Introduction aux sockets 13/24
}
}
Client.java
Code : Java
import java.io.IOException;
import java.net.*;
Socket socket;
try {
socket = new Socket("localhost",2009);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Résulats :
Code : Console
Si vous m'avez bien suivis vous ne devriez pas avoir du mal à comprendre ce code. Dès que quelqu'un tape à la porte, on
demande à un employer de lui ouvrir la porte, celui-là va le saluer et lui dire bye bye avec socket.close(); s'il ne veut pas parler
(communiquer) .
On devra avoir quelque chose de ce genre côté serveur, pour plusieurs clients à la fois :
Code : Console
www.siteduzero.com
Introduction aux sockets 14/24
Code : Console
Demande de connexion
Connexion établie avec le serveur, authentification :
Entrez votre login :
chabanus
Entrez votre mot de passe :
chabanus
Je suis connecté
Votre message :
salut
Le serveur vous dit : salut
Votre message :
ça va ?
Le serveur vous dit : bien et toi ?
Allez au boulot !
…
…
…
Côté Serveur
Accepter_connexion.java
Code : Java
import java.io.*;
import java.net.*;
try {
while(true){
socket = socketserver.accept();
System.out.println("Un zéro veut se connecter ");
www.siteduzero.com
Introduction aux sockets 15/24
}
} catch (IOException e) {
System.err.println("Erreur serveur");
}
}
}
Authentification .java
Code : Java
import java.net.*;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.io.*;
try {
in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
while(!authentifier){
if(isValid(login, pass)){
out.println("connecte");
System.out.println(login +" vient de se connecter ");
out.flush();
authentifier = true;
}
else {out.println("erreur"); out.flush();}
}
t2 = new Thread(new Chat_ClientServeur(socket,login));
t2.start();
} catch (IOException e) {
www.siteduzero.com
Introduction aux sockets 16/24
}
}
while(sc.hasNext()){
if(sc.nextLine().equals(login+" "+pass)){
connexion=true;
break;
}
}
} catch (FileNotFoundException e) {
System.err.println("Le fichier n'existe pas !");
}
return connexion;
Chat_ClientServeur.java
Code : Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
socket = s;
login = log;
}
public void run() {
try {
in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
System.err.println(login +"s'est déconnecté ");
}
}
}
www.siteduzero.com
Introduction aux sockets 17/24
Emission .java
Code : Java
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
sc = new Scanner(System.in);
while(true){
System.out.println("Votre message :");
message = sc.nextLine();
out.println(message);
out.flush();
}
}
}
Reception.java
Code : Java
import java.io.BufferedReader;
import java.io.IOException;
this.in = in;
this.login = login;
}
while(true){
try {
message = in.readLine();
System.out.println(login+" : "+message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
www.siteduzero.com
Introduction aux sockets 18/24
Serveur.java
Code : Java
import java.io.*;
import java.net.*;
try {
ss = new ServerSocket(2009);
System.out.println("Le serveur est à l'écoute du port
"+ss.getLocalPort());
} catch (IOException e) {
System.err.println("Le port "+ss.getLocalPort()+" est déjà
utilisé !");
}
Côté Client
Chat_ClientServeur.java
Code : Java
import java.io.*;
import java.net.*;
import java.util.Scanner;
www.siteduzero.com
Introduction aux sockets 19/24
sc = new Scanner(System.in);
} catch (IOException e) {
System.err.println("Le serveur distant s'est déconnecté !");
}
}
Client.java
Code : Java
import java.io.*;
import java.net.*;
try {
System.out.println("Demande de connexion");
socket = new Socket("127.0.0.1",2009);
System.out.println("Connexion établie avec le serveur,
authentification :"); // Si le message s'affiche c'est que je
suis connecté
} catch (UnknownHostException e) {
System.err.println("Impossible de se connecter à l'adresse
"+socket.getLocalAddress());
} catch (IOException e) {
System.err.println("Aucun serveur à l'écoute du port
"+socket.getLocalPort());
}
Connexion.java
Code : Java
www.siteduzero.com
Introduction aux sockets 20/24
import java.net.*;
import java.util.Scanner;
import java.io.*;
socket = s;
}
try {
while(!connect ){
System.out.println(in.readLine());
login = sc.nextLine();
out.println(login);
out.flush();
System.out.println(in.readLine());
pass = sc.nextLine();
out.println(pass);
out.flush();
if(in.readLine().equals("connecte")){
else {
System.err.println("Vos informations sont incorrectes ");
}
} catch (IOException e) {
Emission.java
Code : Java
www.siteduzero.com
Introduction aux sockets 21/24
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
sc = new Scanner(System.in);
while(true){
System.out.println("Votre message :");
message = sc.nextLine();
out.println(message);
out.flush();
}
}
}
Reception.java
Code : Java
import java.io.BufferedReader;
import java.io.IOException;
this.in = in;
}
while(true){
try {
message = in.readLine();
System.out.println("Le serveur vous dit :" +message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
www.siteduzero.com
Introduction aux sockets 22/24
Lancez serveur.java et ensuite client.java, n'oubliez pas de créer un fichier pour le serveur pour qu'il puisse y vérifier l'identité de
ses clients, je l'ai nommé zero.txt : vous pouvez le nommer comme vous le souhaitez, c'est à votre guise.
Optimisation :
Pour ne pas dire qu'il en existe à l'infini, plusieurs autres possibilités s'offrent à vous, vous pouvez :
rendre l'application client / client. Le serveur authentifie les deux clients et ces deux-là pourront discuter ensemble sans
que d'autres puissent y entrer : grosso modo réaliser un « salon », comme on l'appelle ;
utiliser les bases de données pour la sauvegarde des messages et pour authentifier les clients ;
réaliser une interface graphique en swing ou en awt ;
…
Croyez-moi : lorsque vous maîtriserez les sockets en utilisant les threads, rien ne sera plus compliqué pour vous. Bonne
continuation à tous ; surtout n'hésitez pas à l'améliorer et envoyez-moi un MP pour m'exposer votre travail.
Q.C.M.
Le premier QCM de ce cours vous est offert en libre accès.
Pour accéder aux suivants
Connectez-vous Inscrivez-vous
Quelle est la classe qui permet de créer un socket pour le serveur ?
SocketServer.
ServeurSocket.
SocketServeur.
ServerSocket.
Vrai.
Faux.
Code : Java
try {
ServerSocket ss= new ServerSocket(1026);
ss.close();
Socket s = ss.accept();
} catch (IOException e) {
Correction !
Statistiques de réponses au Q CM
Le mode UDP est plus rapide que le mode TCP mais c'est une communication non fiable, car on ne se préoccupe pas du résultat
de la réception du récepteur, il est donc moins utilisé. Maintenant que vous savez manier les sockets, le mode UDP ne devrait
pas vous poser de problème .
www.siteduzero.com
Introduction aux sockets 23/24
Je vous remercie d'avoir lu le tutoriel, il est à présent terminé. J'espère que vous avez bien suivi
À la prochaine pour un autre tutoriel client/serveur ! La technologie RMI (Remote Method Invocation) ! Qui vous permettra de
mieux comprendre la nature et la fonction des EJB (Entreprise JavaBeans) qui représente l'étendard de la plate-forme J2EE !
Je remercie :
Partager
www.siteduzero.com