Programme serveur

Un programme serveur attend qu'un programme client demande une connexion, puis, lorsque la connexion est établie par l'intermédiaire d'un objet de la classe Socket, répond aux requêtes du client.

La classe ServerSocket

Le package java.net contient la classe ServerSocket qui représente un serveur. Celui-ci est associé à un port qui est un numéro d'identification supérieur à 1024 (les autres numéros sont réservés).

Constructeur

On construit un objet de la classe ServerSocket en indiquant son numéro de port.

        serveur=new ServerSocket(port);

Méthode accept

Après la création du serveur, on utilise la méthode accept pour attendre les tentatives de connexion effectuées par les clients. Lorsqu'une connexion est détectée, la méthode accept renvoie un objet de la classe Socket qui permettra d'établir le dialogue à travers des flots dentrée et de sortie. Le serveur créera alors un processus qui gèrera cette communication par l'intermédiaire d'une classe à créer nommée MaConnexion. Tout se passe à l'intérieur d'une boucle infinie qui peut prendre la forme suivante :

         while (true) {
          //création de nouvelles connexions
          Socket s=serveur.accept();
          new MaConnexion(s);
         } 

C'est la classe MaConnexion qui permet de définir le fonctionnement du serveur.

Programme modèle

Comme la plupart des méthodes utilisées sont susceptibles de provoquer des exceptions, elles seront utilisées dans des structures try...catch... Nous prendrons comme exemple un programme serveur destiné à envoyer l'heure courante, il pourra se présenter sous la forme suivante :

        import java.io.*;
        import java.net.*;

        public class ServHeure {

         static int port;
 
         public static void main(String args[]) {
          ServerSocket serveur;
          //définition du port
          try {
           port=Integer.parseInt(args[0]);
          } catch (Exception e) {
           port=1234;  //valeur par défaut
          }
          //installation
          try {
           serveur=new ServerSocket(port);
           while (true) {
            //création de nouvelles connexions
            Socket s=serveur.accept();
            new MaConnexion(s);
           } 
          } catch (IOException e) {
           System.out.println("Erreur à la creation d'un objet Socket : "+e.getMessage());
           System.exit(1);
          }
         }
        }

Il suffira ensuite de le compléter en définissant la classe MaConnexion.


Gérer la connexion

Lorsque la connexion est établie avec un client, le dialogue client-serveur est gérée par la classe MaConnexion qui va créer un processus par client en implémentant l'interface Runnable.

Nous allons prendre comme exemple un serveur d'heures dont la tâche sera d'envoyer l'heure courante lorsqu'il recevra le message "h".

Déclarations

La classe MaConnexion utilisera trois variables :

On obtient le code suivant :

        class MaConnexion implements Runnable {
         Socket client;               //liaison avec client
         BufferedReader depuisClient; //réception de requête
         PrintWriter versClient;      //envoi des réponses

Le constructeur

Le constructeur est chargé d'initialiser les 3 variables utilisées, d'envoyer un message de bienvenue et de lancer le processus de dialogue.

Le Socket client permet d'obtenir des flots d'entrée et de sortie grâce aux méthodes getInputStream et getOutputStream. Ceci nous donne le code suivant :

        public MaConnexion(Socket client) {
         this.client=client;
         try {
          // création des flots de/vers le client
          depuisClient=new BufferedReader(
            new InputStreamReader(client.getInputStream())); 
          versClient=new PrintWriter(
           new OutputStreamWriter(client.getOutputStream()),true);
          // message d'accueil
          versClient.println("Bienvenue sur le serveur d'heure.");
          versClient.println("Entrez h pour obtenir l'heure.");
          versClient.println("Envoyez une chaîne vide pour fermer la connexion.");
         } catch (IOException e) {
          try { 
           client.close(); 
          } catch (IOException ee) {}
         }
         //mise en route du processus par appel de la méthode run
         new Thread(this).start();
        }

Méthode run

La méthode run (exigée par l'interface Runnable) gère le dialogue en attendant des messages et en répondant aux messages reçus.

Dans notre exemple, seuls les messages "h" sont pris en compte et provoquent l'envoi de l'heure. Les autres messages provoquent l'arrêt de la connexion. Ceci nous donne le code suivant :

         public void run() {
          boolean fini=false; //drapeau
          try {
           String lue;  //la requête
           String rep;  //la réponse
           while (!fini) {
            lue=depuisClient.readLine();
            if (lue==null) fini=true;
            else if (!lue.equals("h")) fini=true;
            else {
             //on envoie l'heure
             Calendar cal=Calendar.getInstance();
             rep="Il est "+cal.get(Calendar.HOUR)+"h"
                +cal.get(Calendar.MINUTE)+"mn"+cal.get(Calendar.SECOND)+"s.";
             versClient.println(rep);
            }
           }
          } catch (IOException e) {
           System.out.println("Exception entrée/sortie : "+e.getMessage());
          } 
          //fermeture de la connexion
          stop();
         }

La méthode stop

Il nous reste à écrire la méthode stop qui met fin à la connexion. Il suffit pour cela d'appeler la méthode close du Socket client.

         public void stop() {
          try {
           versClient.println("Au revoir !");
           client.close();
          } catch (IOException e) {
           System.out.println("Exception à la fermeture d'une connexion : "+e);
          }
         }


Utilisation du programme ServHeure

Après avoir compilé le fichier ServHeure.java, nous pouvons l'exécuter dans une console DOS en utilisant la commande :

java ServHeure

Le serveur attend alors qu'un programme client établisse une connexion. Sous Windows nous pouvons utiliser telnet pour le faire.

On ouvre la connexion en utilisant le menu Connexion et en indiquant l'adresse de l'ordinateur sur lequel fonctionne le serveur (localhost pour votre propre ordinateur) ainsi que le numéro de port 1234. Le message de bienvenue du serveur apparait, puis l'heure est affichée à chaque envoi de la commande "h".

On met fin au programme serveur en activant la console DOS qui a permis de l'exécuter et en appuyant sur la combinaison de touches Ctrl-C.



Retour au menu