Concurrent.java

package fr.umlv.ji.tcp.server;
import java.net.*;
import javax.net.*;
import java.io.*;
import java.util.logging.*;
import java.util.prefs.*;
/**
 * Classe représentant un serveur concurrent.
 */
public class Concurrent extends Server {
  public Concurrent(Logger log, Preferences prefs) {
    super(log,prefs);
  }
  /** Méthode de démarrage du serveur concurrent. Elle accepte des
      connexions de clients et, dans des processus légers concurrents,
      fait exécuter le service par chacun d'eux pour la connexion
      correspondante. */
  public void launch() {
    try {
      bind();
    } catch(IOException e) {
      logger.log(Level.SEVERE,"bind",e);
      return;
    }
    Socket socket;
    while(true) {
      try { // Récupération de la socket d'une connexion pendante
    socket = serverSocket.accept();
      } catch (IOException e) {
    logger.log(Level.SEVERE,"Accept",e);
    break;
      }
      /* Création d'un processus léger exécutant, pour la socket de
         service, le code lié au service à rendre. Ce code est
     représenté par une instance de classe interne anonyme
     retournée par la méthode runnableService(). */
      Thread t = new Thread(runnableService(socket));
      // Le processus léger est marqué "daemon" et démarré
      t.setDaemon(true);
      t.start();
    }
  }
  /** Méthode retournant une instance d'une classe interne,
      représentant ce service appliqué à une socket de service,
      sous la forme d'un objet exécutable par un processus léger. */
  Runnable runnableService(final Socket serviceSocket) {
    return new Runnable() {
      public void run() {
    try {
      logger.info(Thread.currentThread().getName() +
              " traite le service " +
              service.getClass().getName());
      service.serve(serviceSocket);
      serviceSocket.close();
    } catch (IOException e) {
      logger.log(Level.WARNING,e.toString());
    } catch(NullPointerException e) {
      logger.log(Level.SEVERE,"service",e);
    }
      }
    };
  }
}