Looking for Computer Science  & Information Technology online courses ?
Check my new web site: https://www.yesik.it !

Cet article est une reprise de l'article Communication par socket sous Java que j'avais précédemment publié sur http://wiki.esicom-st-malo.fr
Objectifs A la fin de ce tutoriel, vous saurez:
  • Créer un serveur qui attend une requête sur une socket,
  • Créer un client qui se connecte à un serveur par socket.
Prérequis
  • Connaissances de la syntaxe du langage Java,
  • Connaissances élémentaires des E/S sur flux en Java.
Moyens
  • Un environnement de développement Java (au minimum le JDK, ou mieux un IDE comme Eclipse).


Les sockets

En Java, chaque instance de la classe Socket est associé à un objet de la classe InputStream (pour lire sur la socket) et à un objet de la classe OutputStream (pour écrire sur la socket)

Les sockets sont un moyen de communication entre programmes (IPC: inter-process communication) mis au point par l'université de Berkeley. Les sockets permettent à deux processus de communiquer entre eux au travers d'une liaison identifiée par une adresse IP et un numéro de port.

L'interface originelle de Berkeley était pour le langage C, mais depuis les sockets ont été implémentées dans de nombreux langages. Nous allons utiliser ici l'implémentation de Sun pour Java.

Le serveur Dumpy

Dumpy, notre serveur va être extrêmement simpliste, mais pour illustrer la communication par socket, c'est bien assez. Il se contentera donc des opérations suivantes:

  1. Attendre une requête d'un client,
  2. afficher le message reçu,
  3. se terminer.

Comme tout serveur basé sur les sockets, Dumpy utilisera deux sockets. Le première, appelée socket de connection sert à attendre un client. La seconde, appelée socket de communication sert à dialoguer avec le client. Un véritable serveur, comme par exemple un serveur Web, utilise également ces deux sortes de sockets. La socket de connexion correspond à un port bien précis (par ex. 80) qui sert uniquement pour la connexion. Ensuite chaque client dialogue avec le serveur sur sa propre socket de communication.

En Java, créer une socket de connexion peut se faire simplement en instanciant un objet de la classe ServerSocket du package java.net.

/*
 * Instancie une socket de connexion lié au port 10080
 */
ServerSocket conn = new ServerSocket(10080);

Un fois la socket de connexion créée, il suffit de lui demander d'attendre un client et de récupérer la socket de communication qui permettra de dialoguer avec le client:

Socket comm = conn.accept();

On peut ensuite communiquer avec le client en utilisant les flux d'entrée et de sortie associés à la socket. Par exemple, pour lire (et afficher dans la console du serveur) le message envoyé par le client, ou pourra coder:

InputStream is = comm.getInputStream();
int c;
while((c = is.read()) != -1)
  System.out.write(c);

Le code complet

Avec un peu de mise en forme, le code complet de Dumpy ressemble à ceci:

import java.io.*;
import java.net.*;
 
public class Dumpy {
  public static void main(String[] args) throws IOException
  {
    ServerSocket conn = null;
    Socket comm = null;
    InputStream is = null;
 
    try
    {
      conn = new ServerSocket(10080);
      comm = conn.accept();
 
      is = comm.getInputStream();
      int c;
      while((c = is.read()) != -1)
        System.out.write(c);
    }
    catch(Exception e)
    {
      System.err.println("Exception " + e.toString());
    }
    finally
    {
      if (is!=null)
         is.close();
      if (comm!=null)
         comm.close();
      if (conn!=null)
         conn.close();
    }
  }
}

Tester Dumpy

Compilez et lancez Dumpy à partir d'un terminal:

sh$ javac Dumpy.java
sh$ java Dumpy

Ouvrez un second terminal dans lequel vous utiliserez telnet pour communiquer avec Dumpy:

sh$ telnet localhost 10080

Normalement, tout ce que vous tapez dans telnet doit apparaître dans la console de Dumpy (selon la configuration de votre terminal, il peut être nécessaire de taper un retour à la ligne pour que les données soient effectivement transmises).

Le client Sendy

Après avoir étudié le serveur Dumpy, le client Sendy devrait vous sembler assez simple à comprendre. Celui-ci se contente d'envoyer une requête à un serveur et d'afficher la réponse reçue. Dans Sendy tout est codé "en dur": port, message, etc. Il va de soi qu'un client réel serait autrement plus souple. Mais pour les besoins de la démonstration, c'est largement suffisant.

Contrairement au serveur, le client n'utilise qu'une seule socket: la socket de communication:

/*
 * Connexion au serveur et obtention d'une socket
 * de communication
 */
 Socket comm = new socket("localhost", 10080);

On peut ensuite communiquer avec le serveur en utilisant les flux d'entrée et de sortie associés à la socket. Par exemple, pour envoyer un message et afficher la réponse on pourra écrire:

comm.getOutputStream().write("Ceci est mon message\n");
InputStream is = comm.getInputStream();
int c;
while((c = is.read()) != -1)
  System.out.write(c);

Le code complet

Avec un peu de mise en forme, le code complet de Sendy ressemble à ceci:

import java.io.*;
import java.net.*;
 
public class Sendy {
  public static void main(String[] args) throws IOException
  {
    Socket comm = null;
    InputStream is = null;
 
    try
    {
      comm = new Socket("localhost", 10080);
 
      comm.getOutputStream().write("Ceci est mon message\n\n".getBytes());
      is = comm.getInputStream();
      int c;
      while((c = is.read()) != -1)
        System.out.write(c);
    }
    catch(Exception e)
    {
      System.err.println("Exception " + e.toString());
    }
    finally
    {
      if (is!=null)
         is.close();
      if (comm!=null)
         comm.close();
    }
  }
}

Pour tester

Pour tester, vous pouvez commencer par lancer Dumpy dans un terminal, puis Sendy dans un autre. Dumpy devrait afficher le message envoyé par Sendy, et Sendy ... ne rien afficher. En effet, Dumpy ne renvoie rien, donc Sendy attend indéfiniment une réponse qui ne viendra jamais...

Pour tester de façon plus complète Sendy, vous pouvez

Ces deux possibilités sont bien entendu laissées à titre d'exercice personnel!

Voir aussi