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

AWT/Swing Java Discussion :

Conflit repaint/socket en attente (2)


Sujet :

AWT/Swing Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 5
    Points : 7
    Points
    7
    Par défaut Conflit repaint/socket en attente (2)
    Le probleme a déjà été évoqué dans le topic suivant :
    http://www.developpez.net/forums/d88...attente-socket

    Mais je me permets de relancer un nouveau topic puisque l'autre est marqué résolu et que je rencontre le même genre de problème, mais légèrement différent.

    I) --------------------------------------------

    J'implémente donc un jeu de plateau en réseau ; le problème que j'ai rencontré (similaire à celui de bobby51) est que la vue du joueur qui vient de jouer et qui après avoir effectué un repaint, se met en attente de l'état de jeu envoyé par l'autre joueur après son coup, ne se met pas à jour.

    Il y a donc une sorte de conflit entre le repaint de la GUI et les méthodes bloquantes de la communication reseau. J'avoue que je n'arrive pas vraiment à saisir pourquoi... Ca reste très mystérieux pour moi, et après avoir fait pas mal de recherche je n'ai trouvé aucune réponse.

    Par ailleurs j'ai trouvé deux solutions à cela :
    a) implémenter des boites de dialogues de confirmation après le repaint, et qui - si confirmation - envoie le nouvel état de jeu au joueur distant
    b) exécuter un nouveau thread pour chaque "mise en attente" du nouvel état de jeu.

    Donc, en gros ça ne pose pas vraiment problème, mais j'aimerais comprendre un peu plus la raison du conflit (parce que ça m'a pas mal fait galérer :p)

    II) --------------------------------------------

    Au delà de ça, en tombant sur le topic vers lequel je renvoie ci-dessus, je me suis convaincu de passer de mon serveur monothread à un serveur multithread.

    En effet, j'ai commencé par implémenter que le joueur 1 faisait serveur (et n'était pas client local du serveur) et que le joueur 2 était client.

    Par ailleurs, j'envisage d'implémenter des parties réseaux jusque 4 joueurs, donc un serveur multithread s'avère indispensable.

    Après pas mal de recherche sur internet et notamment lecture du livre "TCP/IP Sockets in JAVA, practical guide for programmers" de K.L CALVERT et M.J DONAHOO (édition Morgan Kaufmann) j'avoue que je bloque toujours.

    J'ai bien implémenté un serveur multithread mais le fait est qu'il exécute un nouveau thread (et donc un nouveau socket) à chaque requête d'un client... Or en lisant le topic auquel je renvoie ci-dessus, il est apparement possible et préférable d'implémenter un serveur multithread ou chaque client n'exécute qu'un thread (et donc qu'un seul socket) par partie.

    J'avoue que je bloque totalement là-dessus... Impossible pour moi de concevoir (et donc implémenter :p) cela...

    Merci d'avance pour votre lecture et votre aide !

  2. #2
    Membre averti
    Homme Profil pro
    Freelance
    Inscrit en
    Février 2008
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 312
    Points : 390
    Points
    390
    Par défaut
    salut, en réponse a ton mesage privé, je te met le code que j'ai pour mon serveur multithread. la méthode run de ce thread serveur se met constamment en attente d'une demande de connexion de la part d'un client, quand elle en recoit une elle crée un thread secondaire en lui passant le socket correspondant a ce client, elle ajoute aussi ce thread secondaire a une liste de thread (pour repertorier tous ses clients).

    voici le code du serveur principal
    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
     public thread_serveur(jeu j)
        {
            jeucourant=j;
            Listclient = new ArrayList<thread_client>();
        }
     
        @Override
        public void run()
        {
            try {
                serverSocket = new ServerSocket(7780);
                serverSocket.setSoTimeout(10000);
            } catch (IOException ex) {
                finpartie=true;
            }
     
            while (!finpartie)
            {
                try
                {
                    Socket ts = serverSocket.accept();
                    thread_client tc = new thread_client(jeucourant, ts, this);
                    Listclient.add(tc);
                    tc.start();
                }
                catch (Exception e)
                {
     
                }
            }
            //arret des threads secondaire
            for (int i=0;i<Listclient.size();i++)
            {
                Listclient.get(i).setFinpartie(true);
            }
            try
            {
                serverSocket.close();
            }
            catch (Exception e)
            {
     
            }
        }
    maintenant le code du thread secondaire. Je rappelle il y autant de thread secondaire que de client connectés au serveur. Dans le constructeur de ce thread on crée les input et output nécessaire pour communiquer avec le client. Dans la méthode run() on ets constamment en attente de reception d'une donnée provenant de son client. qu'en on recoit une, on envoie cette donnée au serveur qui va se charger de le renvoyer a tous les clients (grace a la méthode envoyer du thread secondaire).
    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
    public thread_client(jeu j, Socket s, thread_serveur ts)
        {
            jeucourant=j;
            socket = s;
            serveur=ts;
            try
            {
                input = new ObjectInputStream(socket.getInputStream());
                output = new ObjectOutputStream(socket.getOutputStream());
            }
            catch (Exception e)
            {
     
            }
        }
     
        //envoie au client
        public void envoyer(Object o)
        {
            try
            {
                output.writeObject(o);
            }
            catch (Exception e)
            {
     
            }
        }
     
        @Override
        public void run()
        {
            try
            {
                while (!finpartie)
                {
     
                    Object obj=input.readObject();
                    serveur.envoyer(obj);
                }
            }
            catch (Exception e)
            {
                JOptionPane.showMessageDialog(null, e.getMessage());
            }
            try
            {
                output.close();
                input.close();
                socket.close();
            }
            catch (Exception e)
            {
     
            }
    maintenant chez chaque client un thread s'occupe de receptionner les données recus du 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
     
                while (!finpartie)
                {
                    try
                    {
                        obj = input.readObject();
                        if (obj instanceof classe.coup)
                        {
                            //executer un coup
                        }
                        else if (obj instanceof String)//c'est un message
                        {
                          ...
                        {
    voila moi c'est comme ca que ca marche, à noter que mon serveur fait le strict minimum, receptionner et renvoyer a tous le monde, si toi tu as besoin par exemple de receptionner et d'envoyer à tout le monde sauf a toi-meme ton serveur sera un peu plus compliqué
    voila en esperant t'avoir aider bonne chance

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Dubphonic Voir le message
    Donc, en gros ça ne pose pas vraiment problème, mais j'aimerais comprendre un peu plus la raison du conflit (parce que ça m'a pas mal fait galérer :p)
    Avec ta socket tu dois sûrement bloquer l'EDT, qui ne peux donc plus s'occuper de ses affaires...


    L'EDT est le thread qui gère l'affichage, et qui doit exécuter tout le code touchant à l'interface graphique... mais uniquement celui là.

    En gros l'EDT est une grosse boucle qui effectues ses tâches à l'infini :
    • Il (re)dessine les composants lorsque cela s'avère nécessaire.
    • Il traite les événements (souris/clavier, etc).
    • Il traite les tâches divers (Timer Swing, invokeLater()/invokeAndWait()).


    Si tu effectues des opérations lourdes dans une de ces tâches, tu vas retarder d'autant l'EDT, et donc le traitement des autres tâches.


    En gros il y a deux règles à respecter :
    • Toutes les opérations touchant à l'interface graphique doivent être fait dans l'EDT.
    • Toutes les autres opérations doivent être exécuté à l'extérieur de l'EDT, afin de ne pas le gêner.



    a++

  4. #4
    Expert éminent sénior
    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 : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    merci de consulter les FAQs, ton problème (affichage givré) est typiquement celui:ci

    Lors d'un traitement long, l'affichage se fige, que faire ?

  5. #5
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Et accessoirement il existe un tuto expliquant expressément les tenants et aboutissant des interactions entre Swings et les Threads.
    http://gfx.developpez.com/tutoriel/j...ing-threading/

  6. #6
    Futur Membre du Club
    Inscrit en
    Mars 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 5
    Points : 7
    Points
    7
    Par défaut
    Merci à tous pour vos réponses !

  7. #7
    Membre averti
    Homme Profil pro
    Freelance
    Inscrit en
    Février 2008
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 312
    Points : 390
    Points
    390
    Par défaut
    en réponse a ton message privé
    Dans la méthode run() on est constamment en attente de reception d'une donnée provenant de son client." La je pige pas : le thread du client attend un objet provenant de lui même pour dire ensuite au serveur de l'envoyer ?
    j'ai l'impression que tu confond. Les threads clients (ou secondaire ce sera peut-etre plus clair) tourne uniquement du coté serveur
    exemple: un serveur (s1) avec 2 clients connecté dessus (c1 et c2) + lui meme
    3 applications de lancées, on suppose que les clients se son déja connectés au serveur
    appli 1 (jour le role du serveur): 5 thread qui tourne
    //les threads "coté serveur"
    -thread serveur principal qui s'occupe de connecter les clients
    -thread secondaire qui s'occupe des données recues de s1
    -thread secondaire qui s'occupe des données recues de c1
    -thread secondaire qui s'occupe des données recues de c2
    //le thread "coté client"
    - thread qui attend les donnés du serveur

    appli 2 (client quelconque)
    - thread qui attend les donnés du serveur

    appli 3(client quelconque)
    - thread qui attend les donnés du serveur

    lorsque par exemple c1 en voie une données au serveur, cet objet sera recue par le thread secondaire qui s'occupe de c1. une fois recue, il faut renvoyer cette données à TOUS les clients. probleme, le thread qui s'occupe de c1 ne connait que c1, il ne saura pas renvoyer à tous les clients.Pour cela une solution, envoyer la donné au serveur, ensuite le serveur fait un truc du genre "pour tous les threads secondaire renvoyer la donnée a chacun des clients"
    chaque thread secondaire sera équipé d'une méthode pour envoyer la donné à son client
    du coté du thread coté client de chaque client,il se chargera de receptionner la donnée et d'en faire ce que tu veux

    d'ou vient cet objet ?
    ba du client

    maintenant chez chaque client un thread s'occupe de receptionner les données recus du serveur " Ou se trouve se code ? dans un tout nouveau thread ? je sèche un peu aussi la
    ce code se trouve chez CHAQUE client, voir la liste des threads par serveur au dessus, c'est dans ce thread qu'on traitera la donnée

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

Discussions similaires

  1. [Débutant] Problème socket serveur (attente du client)
    Par synolog dans le forum C#
    Réponses: 14
    Dernier message: 20/10/2011, 18h16
  2. Socket : Fermer le socket en attente de connexion
    Par benji1801 dans le forum Entrée/Sortie
    Réponses: 8
    Dernier message: 13/05/2011, 18h32
  3. [Socket] Attente avant l'envoi ?
    Par Invité dans le forum C++
    Réponses: 1
    Dernier message: 21/09/2005, 18h59
  4. [socket] attente de réponse
    Par vasilov dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 19/08/2005, 12h20
  5. [Socket] Attente de lecture
    Par al85 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 22/01/2005, 11h16

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