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

/**
 * Un serveur simpliste qui ne fait rien d'autre que d'ouvrir une soquette
 * et de rester à l'écoute de clients éventuels.  Accepte de multiples 
 * clients en même temps.
 *
 * @author Peter T. Sander
 * @version 1.1  15/11/97
 */

public class ServeurBasic {
	private static final int PORT = 6666;  // par défaut	

    /**
	 * La méthode principale de l'application.  Ne traite pas 
	 * les exceptions.
	 * <P>
	 * Le no. du port est un argument optionel à l'application.
	 *
	 * @param args lezarguments
     */
    public static void main (String args[]) throws IOException,
    											NumberFormatException {	
        int port = PORT;
    	int client = 0;
        // ne fait aucune vérification des arguments
		if (args.length == 1) {
            port = Integer.parseInt(args[0]);
        }
		// crée une soquette de type serveur rattachée au port,
		//  avec timeout au bout de 5min.
		ServerSocket soquetteServeur = new ServerSocket(port, 300);
		// il ne reste qu'à attendre que quelqu'un veuille bien nous parler
		while (true) {
		    // on acceptera toute connexion, et chacune aura
		    //  sa propre soquette
		    Socket soquette = soquetteServeur.accept();
		    Connexion conn = new Connexion(soquette, ++client);
		}
    }
}


/**
 * Chaque connexion vers un client a sa propre soquette et tourne dans
 * son propre thread.
 */

class Connexion extends Thread {
    private Socket soquette;
    private int client;
    private BufferedReader in;
    private PrintWriter out;
	
	/**
	 * Constructeur.
	 *
	 * @param soquette où s'est connecté un client
	 */
    Connexion(Socket soquette, int client){
    	super();
		this.soquette = soquette;
		this.client = client;
		try {
		    // associe des flots en entrée/sortie à la soquette
		    in = new BufferedReader(new 
		    					InputStreamReader(soquette.getInputStream()));
		    out = new PrintWriter(soquette.getOutputStream());
		} catch (IOException e) {
		    try {soquette.close();}
		    catch(IOException ee) {}
		    System.err.println("Exception en ouvrant des " +
		    			"flots entrée/sortie");
		    return;  // pas la peine de trâiner
		}
		this.start();  // allons-y
    }

	/**
	 * La méthode qui fait le boulot.  Elle attend un message du client et elle 
	 * écho bêtement ce que ledit client dit (sur une ligne).  Elle fermera
	 * la connexion quand elle recevra un message vide.
	 */
    public void run() {
	  	try {
		    // envoie un message d'acceuil 
		    out.println("Qu'es' tu veux, client " + client + " ?");
		    out.flush();
		    // et attend tranquillement la réponse...
		    while (true) {
				String msg = in.readLine();
				if (msg != null && !msg.equals("")) {
					System.out.println("Le serveur a reçu du client " + client 
							+ " : " + msg);  // ...qu'il écho au terminal...
					out.println(msg);  // et confirme auprès du client
					out.flush();
				} else {
					break;  // fin de communication
				}
		    }
		} catch (IOException e) {}
		finally {
		    try {
				if (soquette != null) {
				    out.println("");
				    soquette.close();
				}
		    } catch (IOException ee) {}
		}
    }
}
