Serveur generique

Description

Ce serveur générique est destiner a simplifier le developpement de serveur Java.
Il gere plusieur connexion concurente et recupere les ressources des clients deconnecter
Il gere deux evenement qui permette de l'utiliser pour diverse application (Serveur chat, serveur ftp, serveur de jeux...)
Ce serveur est multiThread il lance un thread par connexion client et un thread d'attente de nouveau client

pour le lancer ne pas oublier de lancer la methode start

Ce serveur est proteger par les droits d'auteurs
Toute utilisation est autoriser mais merci de me contacter pour toute modification du code

Je m'escuse pour toutes les faute d'ortographe qui peuvent piqué les yeux des personnes normales

Source / Exemple :


package quintarx.serveur;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.EventListener;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.EventListenerList;
/**

  • change log
  • le thread qui porte le serveur est instacier dans le constructeur du serveur
  • Ajout d'une fonction start pour lancer le serveur
  • Ajout d'une fonction getAllClient() pour recupere les id des client connecter
  • Ajout d'un listener sur la deconnexion des client
  • /
/**
  • @category Serveur Générique Java
  • @author Clément Quintard
  • @version 1.0.1
  • Ce serveur générique est destiner a simplifier le developpement de serveur Java.
  • Il gere plusieur connexion concurente et recupere les ressources des clients deconnecter
  • Il gere deux evenement qui permette de l'utiliser pour diverse application (Serveur chat, serveur ftp, serveur de jeux...)
  • Ce serveur est multiThread il lance un thread par connexion client et un thread d'attente de nouveau client
  • Pour l'instancier vu qu'il implements l'interface Runnable il faut utiliser un thread
  • Serveur srv = new Serveur(1985);
  • srv.start()
  • Ce serveur est proteger par les droits d'auteurs
  • Toute utilisation est autoriser mais merci de me contacter pour toute modification du code
  • Je m'escuse pour toutes les faute d'ortographe qui peuvent piqué les yeux des personnes normales
  • /
public class Serveur extends JFrame implements Runnable { /**
  • Liste des listener lier aux serveurs
  • /
private final EventListenerList listeners = new EventListenerList(); private static final long serialVersionUID = -827253777315364714L; /**
  • Paramettrage du serveur
  • /
/**
  • Nombre de connexion disponnible 100 de base
  • /
private int NBCONNEXION = 100; public int getNbConnexionTotal() { return NBCONNEXION; } /**
  • Le serveur est visible de base
  • /
private boolean SERVEURVISIBLE = true; public boolean getVisible() { return SERVEURVISIBLE; } /**
  • true : affiche le serveur
  • false : cache le serveur
  • /
public void setVisible(boolean v) { SERVEURVISIBLE = v; super.setVisible(v); } /**
  • Message de deconnexion des client
  • /
protected String MESSAGEDECO = "EXIT"; /**
  • @return Message utiliser pour qu'un client ce deconnect du serveur
  • /
public String getMessageDeconnexion() { return MESSAGEDECO; } /**
  • Message utiliser pour qu'un client ce deconnect du serveur
  • @param msg
  • /
public void setMessageDeconnexion(String msg) { MESSAGEDECO = msg; } /**
  • Socket serveur il attent les connexion clientes
  • /
private static java.net.ServerSocket serveur; /**
  • Tableau de socket. une socket par client
  • /
private static java.net.Socket[] connexion; /**
  • les flux d'entrees/sorties pour chaque client
  • /
private static java.io.ObjectInputStream[] entree ; private static java.io.ObjectOutputStream[] sortie; /**
  • tableau des deconnecter
  • /
private static boolean[] Tdeco; /**
  • port du serveur
  • /
private int portSrv; public int getPortServeur() { return portSrv; } /**
  • ******************** les composant de l'IHM
  • /
/**
  • Zone d'affichage de la console du serveur
  • /
private static JTextArea zoneAffichage; /**
  • Bouton qui efface l'historique de la console
  • /
private static Button btn = new Button("effacer l'historique de la console"); /**
  • Thread qui porte mon instance de runnable (du serveur quoi!)
  • /
private Thread thread; /**
  • Cree un serveur avec le nombre de connexion par default
  • @param port d'ecoute du serveur
  • /
public Serveur(int port) { this(port,-1); } /**
  • cree un serveur avec le nombre de connexion definie : nbConnexion>0
  • @param port d'ecoute du serveur
  • @param nbConnexion
  • /
public Serveur(int port,int nbConnexion) { super("Serveur"); if(nbConnexion>0) NBCONNEXION = nbConnexion; portSrv = port; connexion = new Socket[NBCONNEXION]; sortie = new java.io.ObjectOutputStream[NBCONNEXION]; entree = new java.io.ObjectInputStream[NBCONNEXION]; Tdeco = new boolean[NBCONNEXION]; //initialisation du tableau des t deco for(int i =0;i<NBCONNEXION;i++) { Tdeco[i] = false;//personne n'est connecter mais personne n'est deconnecter } Container c = getContentPane(); //nouvelle zone de text zoneAffichage = new JTextArea(); //met en style consolefond noir ecriture blanche zoneAffichage.setBackground(Color.BLACK); zoneAffichage.setForeground(Color.WHITE); //***************************************************** c.add(new JScrollPane(zoneAffichage), BorderLayout.CENTER); c.add(new JScrollPane(btn), BorderLayout.NORTH); btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { zoneAffichage.setText("---EFFACER CONSOLE SERVEUR---"); } } ); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(350,350); //cache le serveur-------------------------------------------------------------------- super.setVisible(SERVEURVISIBLE); zoneAffichage.setText("---CONSOLE SERVEUR---"); thread = new Thread(this); } /**
  • Lance le serveur dans un thread
  • /
public void start() { thread.start(); } /** on gere les listener **/ /**
  • Ajoute un listener sur l'arriver de message au serveur
  • Ces listener serve a gerer le message
  • @param listener le listener a ajouter
  • /
public void addmessageListener(messageListener listener) { listeners.add(messageListener.class, listener); } /**
  • Enleve un listener
  • @param listener a enlever
  • /
public void removemessageListener(messageListener listener) { listeners.remove(messageListener.class, listener); } /**
  • Renvoi un tableau contenant tous les listener de message
  • @return messageListener[]
  • /
public messageListener[] getmessageListener() { return listeners.getListeners(messageListener.class); } /**
  • Ajoute un listener sur la deconnexion
  • listener de deconnexion d'un client
  • @param listener le listener a ajouter
  • /
public void addDeconnexionListener(DeconnexionListener listener) { listeners.add(DeconnexionListener.class, listener); } /**
  • Enleve un listener de deconnexion
  • @param listener a enlever
  • /
public void removeDeconnexionListener(DeconnexionListener listener) { listeners.remove(DeconnexionListener.class, listener); } /**
  • Renvoi un tableau contenant tous les listener de deconnexion
  • @return messageListener[]
  • /
public DeconnexionListener[] getDeconnexionListener() { return listeners.getListeners(DeconnexionListener.class); } /**
  • Ajoute un lister de connexion
  • @param listener
  • /
public void addNouvelleConnexionListener(NouvelleConnexionListener listener) { listeners.add(NouvelleConnexionListener.class, listener); } /**
  • Enleve un listener
  • @param listener a enlever
  • /
public void removeNouvelleConnexionListener(NouvelleConnexionListener listener) { listeners.remove(NouvelleConnexionListener.class, listener); } /**
  • Renvoi un tableau contenant tous les listener de Connexion
  • @return NouvelleConnexionListener[]
  • /
public NouvelleConnexionListener[] getNouvelleConnexionListener() { return listeners.getListeners(NouvelleConnexionListener.class); } /**
  • Renvoi une arraylist d'Integer
  • Chaque integer correspond a la position d'un client connecter
  • @return
  • /
public ArrayList<Integer> getAllClientConnecter() { ArrayList<Integer> lesClient = new ArrayList<Integer>(); for(int i=0;i< Tdeco.length;i++) { if(Tdeco[i]) lesClient.add(new Integer(i)); } return lesClient; } /**
  • Envoi un message de type String au client
  • @param message
  • @param client
  • /
public static void envoyerDonnees(String message,int client) { try { zoneAffichage.append("\nmessage pour "+client+"--> "+message+" \n"); sortie[client].writeObject(message); sortie[client].flush(); } catch(IOException io) { zoneAffichage.append("\nErreur"); } } /**
  • Envoi un message de type Object au client
  • @param message
  • @param client
  • /
public static void envoyerDonnees(Object obj,int client) { try { zoneAffichage.append("\nObjet pour "+client+"--> "+obj.getClass()+" \n"); sortie[client].writeObject(obj); sortie[client].flush(); } catch(IOException io) { zoneAffichage.append("\nErreur"); } } /**
  • Methode d'execution du thread principal du serveur
  • Appeler la methode start pour lancer le serveur
  • (new Thread(new Serveur(1985))).start();
  • /
public void run() { try { //ETAPE 1:preparation d'un socket serveur sur le port portSrv et acceptant NBCONNEXION connexion serveur = new ServerSocket(portSrv,NBCONNEXION); int placeClient; //cette boucle receptionnera toute les connexion try { while(true)//je tourne toujour { //attente de connexion if((placeClient= attendreUneConnexion())<Tdeco.length) { Tdeco[placeClient] = true; //obtenir les flux... obtenirLesFlux(placeClient); //je lance un thread qui s'occupera d'un client gereconnexion maconnexion = new gereconnexion(entree[placeClient],placeClient,this); maconnexion.start(); } else { AfficheConsole("Connexion du client echouer il n'y a plus de place sur le serveur"); } } } catch(IOException ex) { AfficheConsole(ex.getMessage()); } } catch(EOFException eof) { AfficheConsole(eof.getMessage()+"\n lengthclient a interrompu la connexion"); } catch(IOException io) { // trate les eventuelles problemes d'E/S AfficheConsole(io.getMessage()); io.printStackTrace(); } } /**
  • Attend une connexion client
  • @return renvoi la place du client dans le tableau des client du serveur
  • @throws IOException
  • /
public int attendreUneConnexion()throws IOException { Socket s = serveur.accept(); int placeUtiliser = recherchePlaceDispoNible(); if(placeUtiliser < Tdeco.length) { connexion[placeUtiliser] = s; this.AfficheConsole("connexion " + placeUtiliser + " recue de : "+ connexion[placeUtiliser].getInetAddress().getHostName()); } return placeUtiliser; } /**
  • @throws IOException
  • /
public void obtenirLesFlux(int placeClient)throws IOException { // Avoir la sortie sortie[placeClient] = new ObjectOutputStream(connexion[placeClient].getOutputStream()); // vidanger lengthtampon de sorie pour envoyer les informations //d'entete. sortie[placeClient].flush(); //Avoir la sortie entree[placeClient] = new ObjectInputStream(connexion[placeClient].getInputStream()); this.AfficheConsole("J'ai recu les flux"); /**
  • Evenement declancher lor de la réussite d'une nouvelle connexion
  • /
for(NouvelleConnexionListener listener : getNouvelleConnexionListener()) listener.NouvelleConnexion(new MessageEventArgs("Nouvelle connexion au serveur", placeClient,this)); } /**
  • Fonction qui recherche une place disponnible grace au trableau Tdeco
  • @return la place disponnible et renvoi une valeur de la taille du tableau Tdeco si aucune place n'est dispo
  • /
private int recherchePlaceDispoNible() { int i=0; while(i<Tdeco.length && Tdeco[i]) i++; return i; } /**
  • Affiche un message sur la console du serveur
  • Passe automatiquement a la ligne a la fin du message
  • Possitionne la scoll bar en bas de la zone de text
  • @param msg
  • /
public void AfficheConsole(String msg) { zoneAffichage.append(msg+"\n"); //je met la position du scroll en bas zoneAffichage.setCaretPosition(zoneAffichage.getText().length()); } /**
  • Class interne qui gere les connexions des differents clients
  • 2010
  • @author Clement Quintard
  • /
class gereconnexion extends Thread { /**
  • Stream d'entrer du client connecter
  • /
private ObjectInputStream monEntree; /**
  • Position du client courent dans le tableau du serveur
  • /
private int position; /**
  • Instance du serveur qui a cree gere connexion
  • /
private Serveur srv; /**
  • Constructeur du Thread
  • @param en Stream d'entree
  • @param pos position du client dans le tableau du serveur
  • /
public gereconnexion(ObjectInputStream en,int pos,Serveur s) { monEntree = en; position = pos; srv = s; } /**
  • Surcharge de la methode des Thread ne pas l'appler
  • /
public void run() { try { traiterConnexion(); } catch(Exception ex) { zoneAffichage.append(ex.getMessage()); deconnexion(); } } /**
  • gere la reception des données
  • @throws IOException
  • /
public void traiterConnexion()throws IOException { Object message = ""; //traitment des informations!! String msg = ""; do { try { AfficheConsole("Message recu du client : "+position); message = monEntree.readObject(); /**
  • j'envoi le msg a un evenement
  • /
for(messageListener listener : getmessageListener()) { listener.ReceptionMessage(new MessageEventArgs(message, position,this.srv)); } if(message.getClass() == String.class) msg = (String)message; } catch(ClassNotFoundException e) { zoneAffichage.append(e.getMessage()+"\nl'object recu de type inconnu"); } }while (!msg.equals(MESSAGEDECO) && !isInterrupted()); try { fermerUneConnexion(); } catch(IOException ex) { AfficheConsole("---"+ex.getMessage()+"---"); deconnexion(); } } private void deconnexion() { Tdeco[position] = false; /**
  • j'envoi le msg a un evenement
  • /
for(DeconnexionListener listener : getDeconnexionListener()) { listener.deconnexionClient(new MessageEventArgs("", position,this.srv)); } } /**
  • ferme une connexion client et ferme le thread qui s'occupe de cette connexion
  • @throws IOException
  • /
private void fermerUneConnexion()throws IOException { try { monEntree.close(); deconnexion(); sortie[position].close(); entree[position].close(); //connexion[position].close(); this.finalize(); } catch (Exception ex) { zoneAffichage.append("\n---"+ex.getMessage()+"---"); deconnexion(); try { this.finalize(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /**
  • Interface des message listener
  • @author Clement Quintard
*
  • /
public interface messageListener extends EventListener { public void ReceptionMessage(MessageEventArgs arg); } /**
  • Interface des message listener
  • @author Clement Quintard
*
  • /
public interface DeconnexionListener extends EventListener { public void deconnexionClient(MessageEventArgs arg); } /**
  • interface des connexionListener
  • @author Clement Quintard
*
  • /
public interface NouvelleConnexionListener extends EventListener { public void NouvelleConnexion(MessageEventArgs arg); } /**
  • Argument des listener du serveur
  • @author Clement Quintard
*
  • /
public class MessageEventArgs { private Object message; private int position; private Serveur srv; public MessageEventArgs(Object message, int position,Serveur srv) { super(); this.message = message; this.position = position; this.srv = srv; } /**
  • obtien le message sous forme d'objet.
  • Il est du devoir de developpeur de savoir sous quel forme le client l'a envoyer pour pouvoir le caster
  • @return
  • /
public Object getMessage() { return message; } /**
  • obtien la position du client qui a envoyer le message au serveur.
  • Utile pour lui repondre
  • @return int
  • /
public int getPosition() { return position; } public Serveur getServeur() { return this.srv; } } }

Conclusion :


Voila ma première source poser sur ce site

J'espère qu'elle vous aidera dans vos futur développements

mise a jour pour quelque évolution

n'esiter a poster vos remarque et amelioration a apporter

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.