IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Sortir proprement mode Client / Serveur


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Viduc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2009
    Messages
    1 445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2009
    Messages : 1 445
    Billets dans le blog
    2
    Par défaut Sortir proprement mode Client / Serveur
    Bonjour

    Je suis en train de réaliser un petit outil de type client / serveur.

    Voici mes class du côté serveur:

    class principale Serveur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    import CONTROLEUR.C_Accepter_client;
    import java.io.IOException;
    import java.net.ServerSocket;
     
    public class Serveur 
        {
        public static void main(String[] args) 
            { 
            ServerSocket socketserver  ;
            //Socket socketduserveur ;
            //BufferedReader in;
            //PrintWriter out;
            Thread serveurThread;
     
            try 
                {
                // Lancement du serveur, écoute sur le port 2009
                socketserver = new ServerSocket(2009);
                serveurThread = new Thread(new C_Accepter_client(socketserver));
                serveurThread.start();
                System.out.println("Lancement du serveur");
                }
            catch (IOException e) {e.printStackTrace();}
            }
        }
    class C_Accepter_client

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    package CONTROLEUR;
     
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
     
    public class C_Accepter_client implements Runnable
        {
        private ServerSocket socketserver;
        private Socket socket;
        //private int nbrclient = 1;
        private Thread threadChat;
     
     
        public C_Accepter_client(ServerSocket s)
            {this.socketserver = s;}
     
        public void run() 
            {
            try 
                {
                while(true)
                    {
                    this.socket = this.socketserver.accept(); // Un client se connecte on l'accepte
                    System.out.println("Connexion d'un nouveau client");
                    this.threadChat = new Thread(new C_Chat(this.socket));
                    this.threadChat.start();
                    } 
                } 
            catch (IOException e) {e.printStackTrace();}
            }
        }
    class C_Chat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    package CONTROLEUR;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
     
    public class C_Chat implements Runnable
        {
        private Socket socket;
        private PrintWriter out = null;
        private BufferedReader in = null;
        private Thread threadEmission, threadReception;
     
        public C_Chat(Socket s)
            {this.socket = s;}
     
        public void run() 
            {
            try 
                {
                this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                this.out = new PrintWriter(socket.getOutputStream());
                System.out.println("Lancement du chat pour le nouveau client");
                this.threadEmission = new Thread(new C_Chat_Emission(this.out));
                this.threadEmission.start();
                this.threadReception = new Thread(new C_Chat_Reception(this.in));
                this.threadReception.start();
                } 
            //catch (IOException e) {e.printStackTrace();}
            catch (IOException e){System.err.println("s'est déconnecté ");}
            }
        }
    class C_Chat_Emission

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    package CONTROLEUR;
     
    //import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Scanner;
     
    public class C_Chat_Emission implements Runnable
        {
        private PrintWriter out;
        private String message = null;
        private Scanner sc = null;
     
        public C_Chat_Emission(PrintWriter out)
            {
            this.out = out;
            }
     
        public void run() 
            {
            this.sc = new Scanner(System.in);
     
            while(true)
                {
                System.out.println("Votre message :");
                this.message = sc.nextLine();
                this.out.println(message);
                this.out.flush();
                }
            }
        }
    et class C_Chat_Recepion

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    package CONTROLEUR;
     
    import java.io.BufferedReader;
    import java.io.IOException;
     
    public class C_Chat_Reception implements Runnable
        {
        private BufferedReader in;
        private String message = null;
     
        public C_Chat_Reception(BufferedReader in)
            {this.in = in;}
     
        public void run() 
            {
            Boolean active = true;
            while(active)
                {
                try 
                    {
                    this.message = this.in.readLine();
                    System.out.println(this.message);
                    } 
                catch (IOException e) {e.printStackTrace();}
                }
            }
        }
    Je ne vous met pas le code côté client mais c'est la même logique...

    tout fonctionne impec, mes clients et le serveur se parlent sans souci.

    Par contre si je coupe un client (CTR+C) mon serveur part en sucette

    il m'affiche null en boucle ... Je ne vois pas comment intercepter la fermeture d'un client et stopper la socket dans laquelle il est. Dans chacune de mes boucles (genre dans C_Accepter_client ou C_Chat_Reception j'ai essayé de modifier mon catch pour voir si j'arrivais dedans (un essayant avaec un System.out.println ou autre) mais non...

    Merci d'avance pour une aide ou conseil...

  2. #2
    Membre expérimenté Avatar de welcome_59
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 203
    Par défaut
    Par contre si je coupe un client (CTR+C) mon serveur part en sucette
    Peux-tu préciser? Est-ce le fameux
    null en boucle
    ?

    Peux-tu poster le code du client qui, si coupé, provoque le crash du serveur?

    Je ne vois pas comment intercepter la fermeture d'un client et stopper la socket dans laquelle il est
    Ces connexions sont sans état, je vois mal comment tu pourrais connaître la fermeture d'un client. Peut-être avec quelquechose du genre session ...

    Dans chacune de mes boucles (genre dans C_Accepter_client ou C_Chat_Reception j'ai essayé de modifier mon catch pour voir si j'arrivais dedans (un essayant avaec un System.out.println ou autre) mais non...
    Sans avoir regardé le code de très près, il me semble que tu utilises la même socket pour toutes les communications de ton serveur. Peut-être un piste? Essaie de traquer la mort ou la fermeture de ta socket.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Par défaut
    Bonsoir,

    J'ai eu un soucis similaire au tiens il y a peu, mes fermetures de connexion générées des erreurs. Pour résoudre ce soucis déjà j'ai changé au niveau des émissions et réceptions mes par des De plus au niveau des catch (on y rentre que si il y a un soucis de dialogue client / server) j'ai mis une fermeture de la socket et j'y change aussi l’état de ma variable boolean : etatConnexion.

    Ainsi il faut absolument rentrer dans un catch au niveau ou le code pose problème pour indiquer la fin de connexion

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur java, .Net
    Inscrit en
    Janvier 2011
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur java, .Net

    Informations forums :
    Inscription : Janvier 2011
    Messages : 55
    Par défaut
    Bonjour,

    Au lieu d'implémenter l'interface Runnable, tes classes devraient héritées de Thread.
    Tu gérerai ainsi tes processus légers.

    C'est peut-être une piste à exploiter.

  5. #5
    Rédacteur
    Avatar de Viduc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2009
    Messages
    1 445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2009
    Messages : 1 445
    Billets dans le blog
    2
    Par défaut
    Bonjour et merci pour vos réponses.

    Citation Envoyé par welcome_59 Voir le message
    Peux-tu préciser? Est-ce le fameux ?

    Peux-tu poster le code du client qui, si coupé, provoque le crash du serveur?

    Ces connexions sont sans état, je vois mal comment tu pourrais connaître la fermeture d'un client. Peut-être avec quelquechose du genre session ...

    Sans avoir regardé le code de très près, il me semble que tu utilises la même socket pour toutes les communications de ton serveur. Peut-être un piste? Essaie de traquer la mort ou la fermeture de ta socket.
    oui c'est bien le fameux null qui sort en boucle...

    Non ce n'est pas la même socket (du moins j'espère ) car je dès qu'une connexion est accepter une nouvelle socket est créée ...

    Citation Envoyé par Arnau6 Voir le message
    Bonsoir,

    J'ai eu un soucis similaire au tiens il y a peu, mes fermetures de connexion générées des erreurs. Pour résoudre ce soucis déjà j'ai changé au niveau des émissions et réceptions mes par des De plus au niveau des catch (on y rentre que si il y a un soucis de dialogue client / server) j'ai mis une fermeture de la socket et j'y change aussi l’état de ma variable boolean : etatConnexion.

    Ainsi il faut absolument rentrer dans un catch au niveau ou le code pose problème pour indiquer la fin de connexion
    oui j'ai essayé ça justement mais sans résultat. Ce qui est étrange c'est que j'ai l'impression que l'erreur ne va pas au catch. J'ai essayé de mettre des socket.close() et même des println mais je n'obtient rien... du coup le faite de passer une variable de true à false ne stop pas la boucle...

    Citation Envoyé par gandalf72000 Voir le message
    Bonjour,

    Au lieu d'implémenter l'interface Runnable, tes classes devraient héritées de Thread.
    Tu gérerai ainsi tes processus légers.

    C'est peut-être une piste à exploiter.
    ok je vais tester ça toute piste est bonne à prendre

    voici au cas ou mes class du côté client:

    le client (main)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    import CONTROLEUR.C_Chat;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
     
    public class Client 
        {
        private static Socket socket = null;
        private static Thread threadClient;
     
        public static void main(String[] args) 
            {
            try 
                {
                System.out.println("Demande de connexion");
                Client.socket = new Socket(InetAddress.getLocalHost(),2009);  
                System.out.println("Connexion établie avec le serveur, lancement du chat...");
                Client.threadClient = new Thread(new C_Chat(Client.socket));
                Client.threadClient.start();   
                }
            catch (UnknownHostException e) 
                {System.err.println("Impossible de se connecter à l'adresse "+Client.socket.getLocalAddress());} 
            catch (IOException e) 
                {System.err.println("Aucun serveur à l'écoute du port "+Client.socket.getLocalPort());}
            }
        }
    la class chat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    package CONTROLEUR;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
     
    public class C_Chat implements Runnable
        {
        private Socket socket;
        private PrintWriter out = null;
        private BufferedReader in = null;
        private Thread threadEmission, threadReception;
     
        public C_Chat(Socket s)
            {socket = s;}
     
        public void run() 
            {
            try 
                {
                this.out = new PrintWriter(this.socket.getOutputStream());
                this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
     
                this.threadEmission = new Thread(new C_Chat_Emission(this.out));
                this.threadEmission.start();
                this.threadReception = new Thread(new C_Chat_Reception(this.in));
                this.threadReception.start();
                } 
            catch (IOException e) 
                {System.err.println("Le serveur distant s'est déconnecté !");}
            }
        }
    la class emission

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    package CONTROLEUR;
     
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Scanner;
     
    public class C_Chat_Emission implements Runnable
        {
        private PrintWriter out;
        private String message = null;
        private Scanner sc = null;
     
        public C_Chat_Emission(PrintWriter out) 
            {this.out = out;}
     
        public void run() 
            {
            sc = new Scanner(System.in);
     
            while(true)
                {
                System.out.println("Votre message :");
                this.message = this.sc.nextLine();
                this.out.println(this.message);
                this.out.flush();
                }
            }    
        }
    la class reception

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    package CONTROLEUR;
     
    import java.io.BufferedReader;
    import java.io.IOException;
     
    public class C_Chat_Reception implements Runnable
        {
        private BufferedReader in;
        private String message = null;
     
        public C_Chat_Reception(BufferedReader in)
            {this.in = in;}
     
        public void run() 
            { 
            while(true)
                {
                try 
                    {
                    this.message = this.in.readLine();
                    System.out.println("Le serveur vous dit :" +this.message);
                    } 
                catch (IOException e) {e.printStackTrace();}
                }
            }
        }

  6. #6
    Rédacteur
    Avatar de Viduc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2009
    Messages
    1 445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Février 2009
    Messages : 1 445
    Billets dans le blog
    2
    Par défaut
    Alors j'ai finalement trouvé comment gérer le problème.
    Tout d'abord j'ai étendue la class Thread comme le suggérait notre magicien gandalf72000

    Ensuite j'ai modifié la class de réception pour tester le system.in et boucler que si il est prêt. Cela donne ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    package CONTROLEUR;
     
    import java.io.BufferedReader;
    import java.io.IOException;
     
    public class C_Chat_Reception extends Thread
        {
        private BufferedReader in;
        private String message = null;
     
        public C_Chat_Reception(BufferedReader in)
            {this.in = in;}
     
        public void run() 
            {
            Boolean active = true;
            while(active)
                {
                try 
                    {
                    if(this.in.ready()){active=false;}
                    else {System.out.println(this.in.readLine());}
                    } 
                catch (IOException e) {e.printStackTrace();}
                }
            this.interrupt();
            }
        }
    Ensuite j'ai modifié ma class chat pour fermer proprement les autres threads dépendant (emission et lui même ie: chat) et fermer la socket. Cela donne ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
     
    package CONTROLEUR;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
     
    public class C_Chat extends Thread
        {
        private Socket socket;
        private PrintWriter out = null;
        private BufferedReader in = null;
        private Thread threadEmission, threadReception;
     
        public C_Chat(Socket s)
            {this.socket = s;}
     
        public void run() 
            {
            try 
                {
                this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                this.out = new PrintWriter(socket.getOutputStream());
                System.out.println("Lancement du chat pour le nouveau client");
                this.threadEmission = new Thread(new C_Chat_Emission(this.out));
                this.threadEmission.start();
                this.threadReception = new Thread(new C_Chat_Reception(this.in));
                this.threadReception.start();
                Boolean test = true;
                while(test)
                    {
                    if(!this.threadReception.isAlive())
                    //if(!this.socket.isBound())
                        {
                        System.out.println("interruption du thread: "+this.threadEmission.getName());
                        this.threadEmission.interrupt();
                        System.out.println("fermeture de la socket: "+this.socket.toString());
                        this.socket.close(); 
                        test = false; 
                        }
                    }
                System.out.println("interruption du thread: "+this.getName());
                this.interrupt();
                } 
            //catch (IOException e) {e.printStackTrace();}
            catch (IOException e){System.err.println("s'est déconnecté ");}
            }
        }
    Voila, ça fonctionne impec et c'est propre (enfin je pense )

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. H2 Database mode client-serveur
    Par nma dans le forum JDBC
    Réponses: 1
    Dernier message: 23/09/2014, 17h40
  2. Mode Clients Serveur
    Par altair8080 dans le forum NodeJS
    Réponses: 4
    Dernier message: 05/09/2012, 11h34
  3. programmation en mode client serveur
    Par biologue2003 dans le forum Développement
    Réponses: 1
    Dernier message: 09/01/2009, 19h11
  4. Mode Client-Serveur sous Windows XP ?
    Par habilité dans le forum Tcl/Tk
    Réponses: 2
    Dernier message: 21/04/2008, 21h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo