20. Une Application client-serveur

Il est conseillé de lire les pages concernant les classes Socket et SocketServer avant de poursuivre la lecture de cette page.

Nous allons créer un système qui permet à des applets d'afficher des messages sur un système serveur. Lorsque le logiciel de navigation lance l'exécution de l'applet cli, celle-ci se connecte sur le serveur pour obtenir une liste de noms. Cette liste est traitée est insérée dans une objet graphique List (voir awt). Lorsque l'utilisateur presse le bouton "envoi", l'applet transmet le message au serveur, dans le format :

send:nom:message
Lorsque le serveur recoit un message comme celui-ci, il l'affiche sur la console. La liste de noms que le serveur envoie à l'applet est contenue dans un fichier qui est lu à l'initialisation.


Votre browser ne supporte pas les applets Java !En utilisant Netscape Navigator ou Sun HotJava, vous pourriez voir cette applet en cours d'exécution :

Le client - cli.java

import java.awt.*;
import java.applet.*;
import java.io.*;
import java.net.*;
import java.util.StringTokenizer;

public class cli extends Applet implements Runnable {

    final static int serverPort = 11115;

    Thread kicker;
    List beepList;
    TextField messageArea;
    Button sendButton;
    String serverHost;
    
    Socket sk;
    DataInputStream fromServer;
    PrintStream toServer;
    
    public void init() {
        add(new Label("Client"));
        beepList = new List(5,false);
        add(beepList);
        add(new Label("Entrez votre message : "));
        messageArea = new TextField(30);
        add(messageArea);
        sendButton = new Button("Envoi");
        add(sendButton);
        serverHost = getCodeBase().getHost();
    }

    public void start() {
        if (kicker == null) {
            kicker = new Thread(this);
            kicker.start();
        }
    }
    
    public void stop() {
        if (kicker != null) {
            kicker.stop();
            kicker = null;
        }
    }

    public void run() {
        try {
            connect();

            String line;
            while ((line = fromServer.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(line,":",false);
                String token = st.nextToken();
                if (token.equals("beep")) {
                    beepList.addItem(st.nextToken());
                } else if (token.equals("message")) {
                    System.out.println("message du serveur : "+st.nextToken());
                } else if (token.equals("hello")) {
                    showStatus("connected to server");
                    toServer.println("list");
                } else if (token.equals("end")) {
                    showStatus("Entrez votre message et pressez Envoi");
                } else {
                    toServer.println("message:Unknown command");
                    System.out.println("message inconnu du serveur : "+line);
                }
            }
        } catch (IOException e) {
            showStatus("Ne peut pas se connecter au serveur");
        } finally {
            disconnect();
        }
    }

    public boolean action(Event evt,Object arg) {
        if (evt.target instanceof Button) {
            if (evt.target == sendButton)
                try {
                    sendPage();
                } catch (IOException e) {
                    System.out.println("IO : "+e.getMessage());
                }
        } else
            return false;
        return true;
    }

    public void sendPage() throws IOException {
        if (beepList.getSelectedItem() == null) {
            showStatus("Vous devez selectionner un destinataire");
            return;
        }
        if (messageArea.getText().equals("")) {
            showStatus("Vous devez entrer un message");
            return;
        }
        System.out.println("Envoi d'un message a "+beepList.getSelectedItem()+" !");
        toServer.println("send:"+beepList.getSelectedItem()+":"+messageArea.getText());
    }

    public void connect() throws IOException {
        sk = new Socket(serverHost,serverPort);
        fromServer = new DataInputStream(sk.getInputStream());
        toServer = new PrintStream(new DataOutputStream(sk.getOutputStream()));
    }

    public void disconnect() {
        try {
            sk.close();
        } catch (IOException e) {
        }
    }

}

Le serveur - ser.java

/*
 * Serveur multi-clients
 */

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

public class ser {

    static int port;
    
    /** cree une Hashtable avec le nom des personnes atteignables */
    public static Hashtable buildDataBase(String filename) {
        Hashtable db = new Hashtable();
        try {
            DataInputStream fileInput = new DataInputStream(new FileInputStream(filename));
            String line;
            while ((line = fileInput.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(line,":",false);
                db.put(st.nextToken(),st.nextToken());
            }
        } catch (NoSuchElementException e) {
            System.out.println("Erreur de format dans la base de donnees : "+e.getMessage());
            System.exit(1);
        } catch (IOException e) {
            System.out.println("Erreur lors de la lecture de la base de donnees : "+e.getMessage());
            System.exit(1);
        }
        return db;
    }

    public static void main(String args[]) {
        if (args.length != 2)
            System.out.println("usage : ser bdonnee port");
        else {
            ServerSocket server;
            try {
                port = Integer.parseInt(args[1]);
            } catch (NumberFormatException e) {
                System.out.println("le port doit etre une valeur entre 1024 et 65535");
                System.exit(1);
            }
            try {
                server = new ServerSocket(port);
                Hashtable dataBase = buildDataBase(args[0]);
                for (;;)
                    new connection(server.accept(),dataBase);
            } catch (IOException e) {
                System.out.println("erreur a la creation d'un objet Socket : "+e.getMessage());
                System.exit(1);
            }
        }
    }
}

class connection implements Runnable {

    Hashtable db;
    Socket client;
    DataInputStream fromClient;
    PrintStream toClient;
    int somme = 0;
    
    public connection(Socket client,Hashtable db) {
        this.client = client;
        this.db = db;
        
        try {
            // creation des flux de/to le client
            fromClient = new DataInputStream(client.getInputStream());
            toClient = new PrintStream(client.getOutputStream());
            System.out.println("Nouvelle connexion au serveur : "+client);
        } catch (IOException e) {
            try { client.close(); } catch (IOException ee) {}
        }
        new Thread(this).start();
    }

    public void run() {
        try {
            toClient.println("hello");
            String line;
            while ((line = fromClient.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(line,":",false);
                String token = st.nextToken();
                if (token.equals("list"))
                    sendList();
                else if (token.equals("send")) {
                    sendPage(st.nextToken(),st.nextToken());
                    toClient.println("message:Le serveur vous dit merci !");
                } else if (token.equals("message"))
                    System.out.println("message : "+st.nextToken());
                else if (token.equals("exit") || token.equals("quit"))
                    break;
                else
                    toClient.println("message:Unknown command");
            }
            toClient.println("message:bye !");
        } catch (IOException e) {
            System.out.println("Exception entree/sortie : "+e.getMessage());
        }
        stop();
    }
    
    public void stop() {
        try {
            client.close();
        } catch (IOException e) {
            System.out.println("exception a la fermeture d'une connection : "+e);
        }
    }
    
    /** envoie la liste de noms au client */
    public void sendList() {
        for (Enumeration e = db.keys();e.hasMoreElements();) {
            toClient.println("beep:"+(String)e.nextElement());
        }
        toClient.println("end");
    }
    
    /** cette methode est appelee lorsqu'un client demande l'envoi d'un message */
    public void sendPage(String name,String msg) {
        System.out.println("Requete d'envoi du message \""+msg+"\" a "+name);
    }
    
}

Index général - Index concepts - Règles BNF
© 1996, DIP Genève, Alexandre Maret & Jacques Guyot
page générée Fri Jun 21 15:41:41 MET DST 1996