TP7 : Réseau, Thread, GUI, modèles client-serveur 

Premier exercice : un client/serveur simple

Travail à effectuer

Vous allez compiler et faire tourner un serveur de socket et un client, qui ne sont que des dérivés des exemples vus en cours (dans le polycopié, il s'agit du premier exemple du chapitre "Programmation réseau en Java", section "Principe d'un serveur TCP/IP").
  1. Compilez la classe ServeurSimple à partir du fichier

  2.  
      ServeurSimple.java
       
  3. Compilez la classe ClientSimple à partir du fichier

  4.  
      ClientSimple.java
       
  5. Toutes les deux sont des appletications, des applets qui fonctionnent aussi en applications, ou plutôt les applications qui fonctionnent aussi en applets, ou plutôt... Faites-les tourner d'abord en applications, sur la même hôte, puis sur des hôtes différents.

  6. Ces exemples n'ont que peu d'intérêt en tant qu'applets, car il n'y a pas de GUI. Néanmoins, vous êtes suffisamment intéressés pour voir comment ça marche en applets. N'oubliez pas que pour fonctionner en applets il faut écrire des .html, qui comprennent le passage de paramètres. Pour tester vous utiliserez comme d'habitude l'appletviewer, inutile de le répéter...

Deuxième exercice : un serveur acceptant plusieurs connexions simultanées

Le modèle client / serveur ci-dessus est particulièrement limité : Ne déprimez pas, on va revoir tout ça...à commencer par le coté serveur.

Travail à effectuer :

  1. Vous allez créer une classe ServeurBasic qui s'occupera simultanément d'un nomble illimité de clients. Ce serveur sera un application uniquement, tiens, en voici sa définition :
  2. import java.io.*;
    import java.net.*;
    
    /**
     * Un serveur simpliste qui ne fait rien d'autre que d'ouvrir une soquette
     * et de rester à l'écoute de clients éventuels. Accepte de multiples 
     * clients en même temps.
     *
     * @author Peter T. Sander
     * @version 1.1 15/11/97
     */
    
    public class ServeurBasic {
             private static final int PORT = 6666; // par défaut    
    
      /**
              * La méthode principale de l'application. Ne traite pas 
              * les exceptions.
              * <P>
              * Le no. du port est un argument optionel à l'application.
              *
              * @param args lezarguments
       */
       public static void main (String args[]) throws IOException,
                                               NumberFormatException {      
         int port = PORT;
         int client = 0;
         // ne fait aucune vérification des arguments
                if (args.length == 1) {
           port = Integer.parseInt(args[0]);
         }
                // crée une soquette de type serveur rattachée au port,
                // 5 personnes en attente
                ServerSocket soquetteServeur = new ServerSocket(port, 5);
                // il ne reste qu'à attendre que quelqu'un veuille bien nous parler
                while (true) {
                  // on acceptera toute connexion, et chacune aura
                  // sa propre soquette
                  Socket soquette = soquetteServeur.accept();
                  Connexion conn = new Connexion(soquette, ++client);
                }
       }
     }
    
    
    /**
     * Chaque connexion vers un client a sa propre soquette et tourne dans
     *  son propre thread.
     */
    
    class Connexion extends Thread {
       // code à fournir
    }

Aide

Voici la documentation générée à partir de la Solution, ainsi que les deux fichiers .class issus eux-aussi de la solution. Les hackeurs pourront essayer de voir ce qu'ils contiennent à l'aide de la commande : javap ServeurBasic (il y a des flags aussi à utiliser, lisez la doc), ou bien en utilisant le logiciel domaine public mocha, un puissant désassembleur java.

Correction de l'exercice


Troisième exercice : un Talk en java, multiserveurs et multiclients

En vous inspirant du deuxième exercice, il est très facile d'écrire une application de type Talk en java. Nous avons un serveur de socket capable d'instancier un objet qui gère une communication à double sens en tâche de fond ! Hop! Il ne manque qu'une interface graphique et un peu de travail pour avoir un talk !

Il s'agit donc D'une application qui :

Je vous conseille de créer une classe "Dispatcher" non graphique s'occupant de l'interface entre la connexion et les fenêtres graphiques. Ne mélangeons pas les sockets et le graphique SVP !

Vous testerez dans un premier temps votre serveur talk en faisant un telnet sur la machine où tourne votre serveur.

Côté client :

Fenêtre de Talk

Allons plus loin :

Imaginons que l'on veuille aussi que notre application puisse se comporter en client. On clique sur un bouton, et hop, une fenêtre apparaît, nous demandant le nom de l'hôte à contacter. On valide. Si sur cet hôte un serveur attend, une fenêtre Talk se poppe à la fois sur le serveur distant, mais aussi sur le client.

Cette fenêtre, c'est la même des deux côtés, deux instances d'une même classe. Simplement les caractères tapés en entrée côté serveur arrivent sur la fenêtre de sortie côté client, et vice-versa.

  1. Lancement du serveur en background et affichage d'une fenêtre avec un bouton pour initier une nouvelle conversation :
  1. Si on a cliqué dessus : apparition d'une fenêtre de saisie du nom de l'hôte que l'on désire contacter (un serveur de Talk doit tourner dessus)
  1. Une fois ce nom validé par <return>, une fenêtre de Talk de ce type appraît à la fois côté serveur et côté client :
Fenêtre de Talk

Pour tester la correction :

Téléchargez cette archive, décompressez-là et exécutéz-là avec la commande : Lancez cette commande dans deux fenêtre dos ou shell séparées, ou mieux, sur deux machines différentes. Cliquez ensuite sur le bouton "New talk" et entrez le nom de l'hôte que vous désirez contacter.