Les sockets permettent d'implanter des connections réseaux fiables pour qu'un ou plusieurs clients puissent envoyer des requêtes à un serveur distant.
Le serveur utilise la classe ServerSocket pour accepter des connexions de clients.
Quand un client se connecte à un port sur lequel un ServerSocket écoute, le ServerSocket crée une nouvelle instance de la classe Socket pour supporter les communications.
int port = ...; ServerSocket server = new ServerSocket(port); Socket connection = server.accept();
L'exemple précédent montre comment utiliser les classes Socket et ServerSocket ensemble, du côté serveur.
Cependant, il fait abstraction de la gestion des exceptions que vous aurez à supporter.
La méthode accept est dite bloquante.
En effet, le programme reste en attente jusqu'à ce qu'une demande de connexion soit prise en compte et traitée.
Java ne propose pas de primitive non bloquante, ce qui impose un type de programmation particulier, car il paraît incongru de devoir attendre qu'une connexion se fasse.
Typiquement, le code proposé se place dans une boucle infinie qui se termine seulement si une erreur grave se produit.
Réciproquement, un client doit pouvoir se connecter à un serveur.
Le client crée donc une instance de la classe Socket pour établir une connexion synchrone avec le serveur:
String host =...; int port = ...; Socket connection = new Socket(host,port);
Ces trois lignes de code permettent d'établir une connexion fiable avec le serveur.
Pour pouvoir fonctionner, le serveur doit être démarré auparavant.
Dans le cas contraire, le client tenterait de se connecter à un serveur inexistant ce qui, après un time-out se traduirait par la levée d'une exception.
Tout comme pour le serveur, le code présenté ne prend pas en compte la gestion des exceptions. Un code compilable devra intégrer cette gestion.
Une fois les connexions réalisées, il suffit d'obtenir les streams (flux) d'entrée et de sortie auprès de l'instance de la classe Socket en cours.
InputStream in = socket.getInputStream(); InputStreamReader reader = new InputStreamReader(in); BufferedReader istream = new BufferedReader(reader); String line=istream.readlLine();
Ces lignes permettent de recevoir des données.
Chaque ligne de code s'appuie sur les flux de données (les streams) que l'on trouve dans le package java.io et représente une étape dans la prise en compte des flux de données :
OutputStream out = socket.getOutputStream(); PrintWriter ostream = new PrintWriter(out); ostream.println(str); ostream.flush();
Ces quatre nouvelles lignes permettent d'établir un flot de données
sortantes.
Comme précédemment, les streams du package java.io sont utilisées et une chaîne de caractères
est envoyée, en quatre étapes: