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

Entrée/Sortie Java Discussion :

[Débutant] Communication entre deux applications en utilisant les sockets


Sujet :

Entrée/Sortie Java

  1. #1
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut [Débutant] Communication entre deux applications en utilisant les sockets
    bonjour,


    J'ai deux applications java A et B installées sur le même PC. Je souhaite qu'elles échangent des informations entre elles.
    Pour cela j'ai créé un ServerSocket sur une application et un Socket sur la seconde. Tout se passe en local.


    J'ai un impératif de fonctionnement :
    les applications A et B ne sont pas nécessairement lancées dans un ordre précis : A peut être lancée avant B et réciproquement.
    Du coup, l'application client doit attendre le serveur ou le serveur doit attendre le client.

    Je pense que mon code est loin d'être optimisé...

    Pourriez-vous corriger mon code si nécessaire et me donner vos avis ?
    Côté Serveur :
    Code java : 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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package miniserveur;
     
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
     
    /**
     *
     * @author 
     */
    public class Serveur extends Thread
    {
        private final int port = 14000;
        private ServerSocket server;
        private Socket socket;
     
        private ObjectOutputStream out = null;
        private ObjectInputStream in = null;
        private boolean stopThread;
     
     
        public Serveur()
        {
            try
            {
                stopThread = false;
                server = new ServerSocket(port);
                server.setSoTimeout(2000);
            }
            catch (IOException ex)
            {
                stopThread = true;
            }
        }
     
        @Override
        public void run()
        {
            while (!stopThread)
            {
                if (openConnection())
                {
                    System.out.println("Connecté");
                    try
                    {
                        out.writeObject("--Ici le serveur--");
                        out.flush();
     
                        System.out.println((String)in.readObject());
                    }
                    catch (ClassNotFoundException ex)
                    {}
                    catch (IOException ex)
                    {}
                }
                else
                {
                    System.out.println("Pas connecté");
                }
            }
        }
     
        public void closeConnection()
        {
            try
            {
                this.join();
                out.close();
                in.close();
                socket.close();
     
                out = null;
                in = null;
                socket = null;
            }
            catch (IOException ex)
            {}
            catch (InterruptedException ex)
            {}
        }
     
        private boolean openConnection()
        {
            boolean status;
     
            status = false;
            try
            {
                socket = server.accept();
     
                if (socket!=null)
                {
                    if (socket.isConnected())
                    {
                        out = new ObjectOutputStream(socket.getOutputStream());
                        out.flush();
     
                        in = new ObjectInputStream(socket.getInputStream());
                    }
     
                    status = socket.isConnected();
                }
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
     
            return status;
        }
    }


    Côté 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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     
    package miniclient;
     
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    /**
     *
     * @author 
     */
    public class Client extends Thread
    {
        private Socket client;
        private ObjectOutputStream out;
        private ObjectInputStream in;
        private boolean stopThread;
     
     
        public Client()
        {
     
        }
     
        private boolean createClient()
        {
            boolean status;
     
            status = false;
            try
            {
                stopThread = false;
                client = new Socket("localhost", 14000);
     
                if (client!=null)
                {
                    if (client.isConnected())
                    {
                        out = new ObjectOutputStream(client.getOutputStream());
                        out.flush();
                        in = new ObjectInputStream(client.getInputStream());
                    }
                    status = client.isConnected();
                }
            }
            catch (UnknownHostException ex)
            {
                System.out.println(ex.getMessage());
            }
            catch (IOException ex)
            {}
     
            return status;
        }
     
        @Override
        public void run()
        {
            long t;
     
            t = System.currentTimeMillis();
     
            while (!stopThread)
            {
                if (System.currentTimeMillis() > t+2000)
                {
                    if (createClient())
                    {
                        System.out.println("Connecté");
                        try
                        {
                            out.writeObject("--Ici le client--");
                            out.flush();
     
                            System.out.println((String)in.readObject());
                        }
                        catch (ClassNotFoundException ex)
                        {}
                        catch (IOException ex)
                        {}
                    }
                    else
                    {
                        System.out.println("Pas connecté");
                    }
                    t = System.currentTimeMillis();
                }
            }
        }
     
        public void closeConnection()
        {
            try
            {
                stopThread = true;
                this.join();
                in.close();
                out.close();
                client.close();
            }
            catch (IOException ex)
            {}
            catch (InterruptedException ex)
            {}
        }
     
     
    }

    Comme vous pouvez le constater, côté serveur j'appelle dans une boucle while() la méthode openConnection(), qui va vérifier si un client est connecté et le cas échéant créer les buffer d'entrée et de sortie.

    Côté client, le dispositif est similaire : je crée un socket jusqu'à ce que je détecte un serveur.


    Le code fonctionne très bien comme ça : je peux lancer d'abord le serveur puis le client ou l'inverse. Et si une application se ferme, je peux la rouvrir, la communication reprend normalement.

    Ce qui me gêne c'est je crée un Socket ou un SocketServer et mes buffer à chaque itération Du coup, je pense que mes codes sont loin d'être optimisés

  2. #2
    Futur Membre du Club

    Inscrit en
    Janvier 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 4
    Par défaut
    Bonjour

    bon je te suggère un truc pourquoi ne pas coder une seule application qui contient tout (un serveur + un client) tu lances 1 instance de l'application elle devient au début un serveur et attend un client qui va se connecter, tu relance une autre instance de l'application. c'est simple tu fais une classe abstraite Model et 2 classes concrètes Serveur et Client qui en héritent, comme j'ai dit tu lances une instance par défaut elle devient un objet serveur et attend un client , tu relance une 2em instance et tu saisies l'IP et Port sur le quel la 1er instance écoute les connexions une fois tu click sur connecter la 2em instance devient un client et se connecte à la 1er instance , et tu peux faire l'inverse, un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Model model = new Serveur(); // au début de l'exécution
    model = new Client(); // au cas tu click sur connecter...
    j'espère que je t'ai aidé un peu

  3. #3
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    désolé CodeMonkey, mais je n'ai rien compris

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    coté serveur, rien à dire, faire un appel sur accept est la bonne manière d'attendre le client. Coté client, au lieu de faire un boucle active qui controle le temps, utilise un Thread.sleep(2000) pour éviter de charger inutilement le proco et le réseau.

  5. #5
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Merci tchize_ pour cette réponse.

    Mais le fait que je crée des socket et des buffer à chaque tour de boucle n'est pas préjudiciable en terme de performance ou de mémoire ?

    Je crains d'empiler des Socket, ObjectOutputStream et ObjectInputStream inutilement côté serveur et côté client.

    Pour le serveur je précise que j'ai fixé le timeout à 2 secondes, donc toutes les deux secondes, je fais un nouvel accept même si un client est connecté.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    ce n'est pas ce que fait sotimeout accept() ne retournera pas avant qu'un client se connecte.

    Non tu ne vas pas saturer le client, les socket sont nettoyé par le GC, c'est pas 5 objets toutes les 2 secondes qui vont tuer ton process, il est capable d'en créer des 100aine de milliers par seconde et de traiter leur nettoyage sans broncher.

  7. #7
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    ce n'est pas ce que fait sotimeout accept() ne retournera pas avant qu'un client se connecte.
    ah ? Je croyais que le timeout était le temps de blocage de la méthode accept(). Après ce timeout une SocketTimeoutException était levé indiquant qu'aucun client ne s'était connecté pendant le temps défini par sotimeout. J'ai mal compris la doc ?


    Non tu ne vas pas saturer le client, les socket sont nettoyé par le GC, c'est pas 5 objets toutes les 2 secondes qui vont tuer ton process, il est capable d'en créer des 100aine de milliers par seconde et de traiter leur nettoyage sans broncher.
    ah ok, donc rien ne te choque dans ce code ? Tu aurais fait pareil ?


    Mes réflexes C++ font que je suis sans doute trop rigoureux dans la gestion des objets. J'ai l'impression qu'en Java on a un peu plus de liberté dans la manipulation des objets, je me trompe ?
    En lisant les différents sujet du forum java, j'ai parfois l'impression que l'on peut créer des objets sans trop se casser la tête et puis laisser le garbage collector faire le ménage

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    heu oui non t'a raison pour le timeout, mal lu


    en java quand des objet nécessitent un traitement particulier c'est documenté, exemple les streams qui doivent être cloturés. En C++ il n'y a pas de garbage collector, en java si, et il fait bien son boulot, pas la peine de s'en soucier.

    rien de chocant, a un détail. Tu fait le accept dans un Thread. Dans un appli multi client, c'est après avoir récupéré un socket via accept qu'on crée en général un thread dédié à ce client, en passant la socket au thread, mais y a rien de catastrophique dans le code.

    Quand aux streams du serveur, il seront nettoyés quand tu fera appel à closeConnection, qui détruit la socket (et donc ses streams) -> pas de ressources qui seraient perdues.

  9. #9
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    rien de chocant, a un détail. Tu fait le accept dans un Thread. Dans un appli multi client, c'est après avoir récupéré un socket via accept qu'on crée en général un thread dédié à ce client, en passant la socket au thread, mais y a rien de catastrophique dans le code.
    Comment ferais-tu dans ce cas ?

    Si l'utilisateur lance plusieurs instances des applications cliente ou serveur je risque d'avoir des conflits. Je dois utiliser des classes singleton ?

  10. #10
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    un serveur, normalement (fin ça dépend de ton cahier de charge hein) ca gère N clients, donc N threads, c'est l'implémentation la plus facile. Basiquement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while(!stop){
      try{
        Socket s = server.accept();
        if (issocketValid(s)) // tu fais tes tests de l'état de la connection là dedans
          new ClientThread(s).start();
      } catch (blablabla) 
         //.....
    }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class ClientThread extends Thread {
      // .....
      public ClientThread(Socket s){
         this.s=s;
      }
      public void run(){
         // utiliser la socket s et commencer à dialoguer avec le client.  
      }
    }
    après tout, il est très rare que le serveur ne doive servir qu'un seul client.

  11. #11
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Les sockets ne seraient pas unidirectionnels par hasard ?
    Quand j'exécute mon code ci-dessus j'ai côté client :
    Connecté
    --Ici le serveur--
    Connecté
    --Ici le serveur--
    Connecté
    --Ici le serveur--
    Connecté
    --Ici le serveur--
    Connecté
    --Ici le serveur--
    Connecté
    --Ici le serveur--
    mais côté serveur :
    Connecté
    --Ici le client--
    Accept timed out
    Pas connecté

    Connecté
    --Ici le client--
    Accept timed out
    Pas connecté

    Connecté
    --Ici le client--
    Accept timed out
    Pas connecté

    Connecté
    --Ici le client--
    Accept timed out
    Pas connecté

    Connecté
    --Ici le client--
    Accept timed out
    Pas connecté

    Connecté
    --Ici le client--
    Une fois sur deux le serveur se déconnecte puis se reconnecte Que se passe-t-il ?
    Côté client je ne remarque pas ce problème.


    J'ai tenté de créer N threads dès qu'un client se connecte, mais comment je peux faire pour m'adresser à 1 client en particulier. Surtout qu'avec le problème que j'évoque ci-dessus, je perds le client par intermittence.

  12. #12
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    alors, tu va retirer les catche vide pour avoir les exceptions.

    Ensuite, ton client se connecte à chaque boucle avec une nouvelle socket, il est donc normal que tu aie une nouvelle connection Les timeout, c'est parce que ton client attends le même temps que le serveur, ce qui amène le serveur à faire son timeout. Fait tourner ton client tous les secondesavec un timeout à deux sur le serveur et tu n'aura plus de soucis.

    Pour ce qui est de distinguer les client, c'est à ça que sert l'objet Socket recu par accept(), ca représente ta communication avec 1 client, d'ou l'intéret de le passer à un thread qui gère exclusivement ce client.

  13. #13
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    bon je commence à y voir plus clair, mes clients communiquent bien avec mon serveur.

    Mon code côté serveur :
    Code java : 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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package miniserveur;
     
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.io.IOException;
     
    /**
     *
     * @author 
     */
    public class Serveur extends Thread
    {
        private final int port = 14100;
        private ServerSocket server;
        private Socket socket;
     
        private boolean stopThread;
        private ThreadClient client = null;
        private int counter = 0;
     
     
        public Serveur()
        {
            try
            {
                stopThread = false;
                server = new ServerSocket(port);
                server.setSoTimeout(2000);
            }
            catch (IOException ex)
            {
                stopThread = true;
            }
        }
     
        @Override
        public void run()
        {
            while (!stopThread)
            {
                if (openConnection())
                {
                    System.out.println("Connecté");
                }
                else
                {
                    System.out.println("Pas connecté");
                }
            }
        }
     
        public void closeConnection()
        {
            try
            {
                stopThread = true;
                client.closeClient();
                this.join();
            }
            catch (InterruptedException ex)
            {}
        }
     
        private boolean openConnection()
        {
            boolean status;
     
            status = false;
            try
            {
                socket = server.accept();
     
                if (socket!=null)
                {
                    if (socket.isConnected())
                    {
                        counter++;
                        client = new ThreadClient(socket, counter);
                        client.start();
                    }
     
                    status = socket.isConnected();
                }
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
     
            return status;
        }
    }

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    package miniserveur;
     
     
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    /**
     *
     * @author 
     */
    public class ThreadClient extends Thread
    {
        private Socket socket = null;
        private ObjectOutputStream out = null;
        private ObjectInputStream in = null;
        private boolean stopThread;
        private int idSocket;
     
        public ThreadClient(Socket socket, int idSocket)
        {
            this.idSocket =  idSocket;
            stopThread = false;
            try
            {
                this.socket = socket;
                out = new ObjectOutputStream(this.socket.getOutputStream());
                out.flush();
                in = new ObjectInputStream(this.socket.getInputStream());
            }
            catch (IOException ex)
            {
                stopThread = true;
            }
        }
     
        @Override
        @SuppressWarnings("SleepWhileHoldingLock")
        public void run()
        {
            while (!stopThread)
            {
                try
                {
                    ThreadClient.sleep(500);
                }
                catch (InterruptedException ex)
                {}
     
                try
                {
                    out.writeObject("--Ici le serveur-- " + this.idSocket);
                    out.flush();
     
                    System.out.println((String)in.readObject());
                }
                catch (ClassNotFoundException ex)
                {
                    closeClient();
                }
                catch (IOException ex)
                {
                    closeClient();
                }
            }
        }
     
        public void closeClient()
        {
            try
            {
                stopThread = true;
                in.close();
                out.close();
                this.socket.close();
     
                in = null;
                out = null;
                socket = null;
            }
            catch (IOException ex)
            {}
     
            try
            {
               this.join();
            }
            catch (InterruptedException ex)
            {}
        }
    }
    Par contre je me suis aperçu de trois choses :
    - le ObjectInputStream est bloquant. Tant que le client n'envoie rien, le serveur est en attente. Comment faire pour cet objet ne soit plus bloquant ?
    J'ai essayé avec la méthode avaible() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (in.avaible>0)
     System.out.println((String)in.readObject());
    mais je reste bloqué quand même

    - le join() dans la méthode closeClient() détruit le thread ! donc tout le code qui suit n'est pas exécuté.

    - dans de nombreux exemples j'ai constaté qu'après la méthode accept() on créait un nouveau thread mais qu'on ne mémorisait pas son instance, pourquoi ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    socket = server.accept();
    new ThreadClient(socket, counter);

  14. #14
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par Auteur Voir le message
    - le ObjectInputStream est bloquant. Tant que le client n'envoie rien, le serveur est en attente. Comment faire pour cet objet ne soit plus bloquant ?
    J'ai essayé avec la méthode avaible() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (in.avaible>0)
     System.out.println((String)in.readObject());
    mais je reste bloqué quand même
    ObjectInput/OutputStream est bloquant, rien à y faire à part ne pas l'utiliser si le blocage te pose problème. Available te repond true car il y a des entete "Objet" présents, du à la création de l'autre coté de l'ObjectOutputStream, mais il n'y a pas nécessairement d'objet sérialisé dans la bête
    - le join() dans la méthode closeClient() détruit le thread ! donc tout le code qui suit n'est pas exécuté.
    Nié?? Le join , ca attends que le thread en question (t dans la commande t.join()) aie fini son travail. tu l'appelle comment ta méthode closeClient()? Es-tu sur que ce ne serait pas plutot ton thread courant qui attends patiement que le join se fasse, join qui ne se fait pas parce que le thread visé par le join est bloqué sur l'objetInputStream à attendre un objet, et donc ne sort pas de la méthode run()? Aussi, je serais toi je mettrais un message dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            catch (InterruptedException ex)
            {}
    pour avoir l'exception, ne JAMAIS mettre de bloc catch vide! Si l'exception se délenche on ne le saura jamais, on ne la traitera pas et le programme donnera juste l'impression de se comporter bizzarement!
    - dans de nombreux exemples j'ai constaté qu'après la méthode accept() on créait un nouveau thread mais qu'on ne mémorisait pas son instance, pourquoi ?
    Si le thread est capable de gérer tout seul le client sans intervention ultérieur, il n'y a pas nécesité de garder un référence vers le thread, puisqu'on en fera rien!

    Note: bien distinguer le thread (unité d'exécution que tu viens de lancer via un appel à start()) et le Thread, objet java qui représente ce Thread. Ce n'est pas parce que tu "jette" l'objet Thread, que le thread va arrêter de fonctionner

  15. #15
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    ObjectInput/OutputStream est bloquant, rien à y faire à part ne pas l'utiliser si le blocage te pose problème. Available te repond true car il y a des entete "Objet" présents, du à la création de l'autre coté de l'ObjectOutputStream, mais il n'y a pas nécessairement d'objet sérialisé dans la bête
    arf... Je dois donc utiliser des threads pour mes input et output ? Ou existe-t-il des objets similaires non bloquants ?

    Citation Envoyé par tchize_ Voir le message
    Aussi, je serais toi je mettrais un message dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            catch (InterruptedException ex)
            {}
    pour avoir l'exception, ne JAMAIS mettre de bloc catch vide! Si l'exception se délenche on ne le saura jamais, on ne la traitera pas et le programme donnera juste l'impression de se comporter bizzarement!
    question naïve : je fais quoi si l'exception se déclenche à part la remonter vers la classe appelante ?

  16. #16
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    la logguer par exemple, histoire que le jour ou ton programme se comporte bizzarement, tu sache quelle exception en est la cause.

  17. #17
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par tchize_
    Note: bien distinguer le thread (unité d'exécution que tu viens de lancer via un appel à start()) et le Thread, objet java qui représente ce Thread. Ce n'est pas parce que tu "jette" l'objet Thread, que le thread va arrêter de fonctionner
    Ok j'ai compris

    Citation Envoyé par tchize_ Voir le message
    la logguer par exemple, histoire que le jour ou ton programme se comporte bizzarement, tu sache quelle exception en est la cause.
    C'est le fameux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Logger.getLogger(ThreadClient.class.getName()).log(Level.SEVERE, null, ex);
    qui gère ça ?


    Sinon pour mes ObjectInput / OutputStream existe-t-il des objets similaires non bloquants ou dois-je utiliser des threads : un pour les entrées un pour les sorties ?

  18. #18
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Ok j'ai résolu mon problème.
    Je dois créer des thread pour chaque opération : 1 thread pour la lecture et 1 thread pour l'écriture.

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

Discussions similaires

  1. [WPF][WCF] Communication entre deux applications
    Par DotNET74 dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 16/08/2010, 20h54
  2. Réponses: 2
    Dernier message: 16/02/2009, 10h31
  3. Communication entre deux applications
    Par Jeff62000 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 26/11/2007, 19h41
  4. Débutant, Communication entre deux programmes
    Par Madalen dans le forum Langage
    Réponses: 5
    Dernier message: 23/05/2007, 22h27
  5. communication entre deux applications
    Par ilhamita dans le forum Langage
    Réponses: 1
    Dernier message: 06/03/2007, 15h28

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