L'exemple est ici de type client-serveur. Un serveur attend des clients pour leur rendre le service suivant : le client envoie un texte issu d'un fichier de type texte, ligne par ligne, et le serveur compte le nombre total de mots du texte.
Le client indique sur la ligne de commande le nom d'un fichier dont il veut compter les mots et le nom de la machine serveur. Le port du serveur sur lequel se fait l'attente de demande de connexion a été fixé dans le programme et vaut 10302. Lorsque le texte a été totalement envoyé, le client envoie la chaîne de caractères "*+*+*+*+" pour indiquer au serveur la fin de l'envoi.
Voici le programme client.
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; class Client { public static void main(String[] arg) { int portEcouteServeur = 10302; BufferedReader lecteurFichier; BufferedReader entree; PrintStream sortie; String ligne; Socket socket; try { socket = new Socket(arg[1], portEcouteServeur); lecteurFichier = new BufferedReader(new FileReader(arg[0])); entree = new BufferedReader(new InputStreamReader(socket.getInputStream())); sortie = new PrintStream(socket.getOutputStream()); while ((ligne = lecteurFichier.readLine()) != null) sortie.println(ligne); sortie.println("*+*+*+*+"); System.out.println(entree.readLine()); sortie.close(); entree.close(); socket.close(); } catch(FileNotFoundException exc) { System.out.println("Fichier introuvable"); } catch(UnknownHostException exc) { System.out.println("Destinataire inconnu"); } catch(IOException exc) { System.out.println("Probleme d'entree-sortie"); } } }Le programme serveur est un peu plus long. La méthode principale crée un socket d'écoute puis, dans une boucle sans fin, utilise le socket d'écoute pour attendre des clients. Pour chaque client, le programme ouvre un socket de communication avec ce client puis instancie pour ce client la classe Service, que nous avons définie, destinée à rendre le service (recevoir un texte ligne par ligne et en compter les mots).
Pour permettre au serveur de gérer plusieurs clients à la fois, la classe Service étend la classe Thread et effectue le travail de réception des lignes de texte et de dénombrement des mots dans sa méthode run. Plus précisément, le constructeur de la classe Service ouvre un flux d'entrée et un flux de sortie sur le socket de communication puis démarre le thread ; durant la méthode run, le thread reçoit le texte ligne par ligne et utilise la classe StringTokenizer pour compter les mots ; lorsque la ligne reçue est *+*+*+*+, le nombre de mots est envoyé par le socket au client.
Les techniques de base relatives à la communication réseau sont en grande partie les mêmes que celles de la classe Client visible ci-dessus.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.StringTokenizer; class Service extends Thread { Socket socket; BufferedReader entree; PrintStream sortie; Service(Socket socket) { this.socket = socket; try { entree = new BufferedReader(new InputStreamReader(socket.getInputStream())); sortie = new PrintStream(socket.getOutputStream()); this.start(); } catch(IOException exc) { try { socket.close(); } catch(IOException e){} } } public void run() { String texte; int compteur = 0; try { while(!(texte = entree.readLine()).equals("*+*+*+*+")) compteur += (new StringTokenizer(texte, " ,.;:_-+*/\\.;\"'{}()=><\t!\n")).countTokens(); sortie.println("votre texte possede " + compteur + " mots"); sortie.close(); entree.close(); socket.close(); } catch(IOException e) {} } } class Serveur { public static void main(String[] arg) { int portEcoute = 10302; ServerSocket standardiste; Socket socket; try { standardiste = new ServerSocket(portEcoute); while(true) { socket = standardiste.accept(); new Service(socket); } } catch(IOException exc) { System.out.println("probleme de connexion"); } } } }Si on lance la commande :
Vous pouvez accéder à :
© Irène Charon, Télécom ParisTech, 2011