La classe java.net.Socket et de java.net.ServerSocket
Le programme suivant se connecte à un serveur d'heure qui tourne en permanence et récupère l'heure. Ici on se sert des sockets pour établir la connexion .
Programme client : CliHeure.java
l'exemple d'un programme qui récupère l'heure sur un serveur web et qui l'affiche à l'écran:
import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; public class CliHeure extends Frame implements Runnable, ActionListener { int portServeur; String adresseServeur; Thread processus=null; Label heure=new Label("Connexion au serveur d'heure"); Socket sk; BufferedReader depuisServeur; PrintWriter versServeur; public CliHeure(String adresse, int port) { portServeur=port; adresseServeur=adresse; addWindowListener(new Fermeture()); Panel p=new Panel(); p.setBackground(Color.white); add(BorderLayout.CENTER,p); p.setLayout(new GridLayout(2,1)); p.add(heure); heure.setAlignment(Label.CENTER); Panel p1=new Panel(); p.add(p1); Button b=new Button("Heure"); p1.add(b); b.addActionListener(this); pack(); processus=new Thread(this); processus.start(); } public void run() { boolean fini=false; try { connect(); String ligne; while (!fini) { ligne=depuisServeur.readLine(); if (ligne==null) fini=true; else if (ligne.startsWith("Au revoir")) fini=true; else if (ligne.startsWith("Il est")) heure.setText(ligne); } } catch (IOException e) { heure.setText("Connexion impossible."); } finally { processus=null; } } public void connect() { try { sk=new Socket(adresseServeur,portServeur); depuisServeur=new BufferedReader( new InputStreamReader(sk.getInputStream())); versServeur=new PrintWriter( new OutputStreamWriter(sk.getOutputStream()),true); //demander l'heure versServeur.println("h"); } catch (Exception e) { heure.setText(e.toString()); } } public void disconnect() { try { sk.close(); } catch (IOException e) { } } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Heure")) versServeur.println("h"); } class Fermeture extends WindowAdapter { /** * Gestion de l'événement Cas de fermeture */ public void windowClosing(WindowEvent e) { versServeur.println(""); disconnect(); System.exit(0); } } public static void main(String args[]) { System.out.println("Chargement en cours..."); CliHeure cli=new CliHeure("localhost",1234); cli.setTitle("Heure"); cli.setVisible(true); } }
Analysons le code
On veut se connecter au serveur d'heure et récuperer l'heure exacte . Dans ce cas on a besoin de Variables permettant d'établir la connection et de dialoguer avec le serveur. Pour établir la connexion on déclare la variable sk de type Socket ( voir la ligne Socket sk ; ) ; mais pour établir la connexion il faut connaître : l'adresse ( le nom du serveur qui propose le service et le numéro du port sur lequel le service est disponible; cela nous emmène à déclarer les varibles:
int portServeur; <--- port de communication String adresseServeur; <--- nom ou adresse de la machine serveur Thread processus=null; <--- processus permet de parallèliser les demandes
Ensuite, dans le constructeur on initialise les variables et on lance le processus via le Thread processus . La gestion de la communnication et l'échange d'informations sont gérées par la méthode run() (n'oublions pas que notre classe implements une interface Runnable).
On tente donc de se connecter au serveur spécifié via le port adéquat.
On voit bien qu'on a ainsi demandé un service en donnant toutes les précisions permettant d'être bien servi. Construisons metenant le serveur (il doit être lancé avant tout programme client).
deuxième programme serveur : ServHeure.java
import java.io.*; import java.net.*; import java.util.*; 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); System.out.println("Serveur d'heures OK."); 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); } } } /** * La classe MaConnexion crée un processus de dialogue avec le client */ class MaConnexion implements Runnable { Socket client; //liaison avec client BufferedReader depuisClient; //réception de requête PrintWriter versClient; //envoi des réponses //Constructeur 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(); } //processus de dialogue public void run() { boolean fini=false; 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(); } public void stop() { try { versClient.println("Au revoir !"); client.close(); } catch (IOException e) { System.out.println("Exception à la fermeture d'une connexion : "+e); } } }
Analysons le code
Ici , comme dans le premier programme , on doit définir un certain nombre de variables permettant, de présenter le service que propose le serveur, d'une part et d'autre part des variables permettant l'échange d'informations avec les éventuels clients.
static int port; <---- le port ..... ServeurSocket serveur = new ServerSocket(port); <---- le serveur ....... Socket client; <---- liaison avec client BufferedReader depuisClient; <---- réception de requête PrintWriter versClient; <---- envoi des réponses La classe interne Maconnexion Runnable va gérer les connexions à travers la méthode run()