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 :

affichage non rafraichi avant attente d'un socket


Sujet :

AWT/Swing Java

  1. #1
    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 affichage non rafraichi avant attente d'un socket
    bonjour a tous
    voila je développe un petit jeu en réseau (jeu du yin-yang, pas très connu mais très intéressant)
    j'en suis a envoyé mes coups par le réseau, cela marche très bien mais j'ai un probleme au niveau de l'affichage
    chaque joueur fait a tour de rôle office de serveur et de client
    un coup se passe de cette manière
    1) j1 choisi un coup
    2)execution du coup chez j1
    des labels, des images sont censés changé sur ma vue
    3) envoie du coup a l'autre joueur j2
    lorsque l'autre joueur recoit le coup on l'execute, la vue est bien mis a jour chez lui
    4)attente chez j1 de reception du coup de l'autre joueur
    c'est la que ca doit bloquer, tant qu'on n'a pas recu le coup de l'autre joueur la vue ne se met pas a jour, du coup quand on recoit le coup il fait l'affichage du coup qu'on a envoyer puis l'affichage du coup qu'on vient de recevoir

    ce que j'ai essayé pour l'instant:
    -faire une pause dans le programme pour que la vue ai le temps de se mettre a jour: Thread.sleep(1000);:ne marche pas
    -forcer l'affichage de la jframe
    majframe.repaint;:marche pas

    voila j'ai plus trop de solution

    je vous met un peut de code si ca peut vous aider
    merci d'avance pour vos réponse

    execution graphique du coup:
    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
    leCoup.executer();
          //on maj le label graphique en se servant de l'attribut imageicon du pion
          if (leCoup.getCasedepart().estvide())
          {
              plateauG.get(getindice(leCoup.getCasedepart())).setIcon(ICtransp);
          }
          else
          {
              plateauG.get(getindice(leCoup.getCasedepart())).setIcon(leCoup.getCasedepart().getpion(leCoup.getCasedepart().getListpion().size()-1).getImage());
          }
          plateauG.get(getindice(leCoup.getCasearrive())).setIcon(leCoup.getCasearrive().getpion(leCoup.getCasearrive().getListpion().size()-1).getImage());
          if (leCoup.getCasedepart().getNumcase()==1)
          {
              pionsJ1.setText(String.valueOf(leCoup.getCasedepart().getListpion().size()) + " pions restant");
          }
          else if (leCoup.getCasedepart().getNumcase()==2)
          {
              pionsJ2.setText(String.valueOf(leCoup.getCasedepart().getListpion().size()) + " pions restant");
          }
          txt_historique.setText(txt_historique.getText() + "\n" +leJoueur.getNom()+" -> pion déplacé de la case "+leCoup.getCasedepart().getNumcase()+" à la case "+leCoup.getCasearrive().getNumcase());
          leJoueur=autrejoueur();
          labelJcourant.setText(leJoueur.getNom()+" A VOUS DE JOUER !");
    envoie du coup a l'autre joueur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                          try
                          {
                              socket = new Socket(leJoueur.getAdresse(), 7776);
                              // construction de flux objets à partir des flux de la socket
                              output = new ObjectOutputStream(socket.getOutputStream());
                              output.writeObject(leCoup);
                          }
                          catch (Exception e)
                          {
                              JOptionPane.showMessageDialog(this, "la liaison est rompu"+e);
                              //fermer la partie
                          }
    attente du coup de l'autre joueur
    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
    labelJcourant.setText("en attente de "+ leJoueur.getNom());
            //on fait une pause pour l'affichage des labels
            //Thread.sleep(10000);
            //this.repai
            //on attend le coup de l'autre joueur
            serverSocket = new ServerSocket(7776);
            //on considère que le joueur a 30s pour jouer
            //voir a mettre un timer de son coté
            serverSocket.setSoTimeout(30000);
            // se met en attente de connexion de la part d'un client distant
            socket = serverSocket.accept();
            // connexion acceptée : récupère les flux objets pour communiquer
            // avec le client qui vient de se connecter
            input = new ObjectInputStream(socket.getInputStream());
            // attente les données venant du client
            leCoup = (coup)input.readObject();

  2. #2
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Ton architecture est compliquée, tu dois absolument faire le serveur d'un côté et le client de l'autre. Il ne faut pas mélangé, ça va devenir très vite une usine à gaz
    Voici une possibilité :
    Le client envoie un coup au serveur. Si le serveur valide le coup, alors il envoie sa validation à tous les clients qui peuvent rafraichir leur interface. Tu n'est donc plus obligé de semer du code serveur un peu partout dans le code du client.
    Le serveur peut être une application à part ou alors un thread à part lancé à partir de l'interface client.

  3. #3
    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
    je m'en rend compte que ca commence a etre le bordel
    mais je ne voit pas comment faire autrement, vu que c'est un jeu qui se joue a deux et a tour de role, pendant que l'un décide de faire son coup, l'autre attend la reception
    Le serveur peut être une application à part
    pas possible c'est un projet scolaire j'ai des contraintes qui m'empeche de mettre en place cette solution, meme si ce serait la plus simple et la plus propre a mettre en place
    ou alors un thread à part lancé à partir de l'interface client
    ok mais du coup qui ferait le role du serveur? imaginons que je decide que ce soit j1 qui fasse le role du serveur, j'active un thread qui attend un coup.
    Dans l'interface de j1 lorsque je fait un coup, je me l'envoie a moi-meme?
    et si je fait un coup chez j2: j'envoie mon coup chez j1, reception par le thread, qui renvoie le coup chez j1 et j2, ce serai donc j1 + j2 qui serait muni de méthode d'attente de coup, puis execution et affichage du coup chez chacune des joueurs. ensuite il faudrai que j1 attende le coup de j2 avant de pouvoir continuer, ca ne solutionne donc pas mon probleme. bref, j'en suis au point de départ mais de facon beaucoup plus compliqué...
    la solution de chaque instance de l'appli est a la fois client et serveur n'est certes pas idéale, pas très propre, mais pour ce que je veux faire je pense que c'est le mieux a faire, ces coups sont la seule chose qui transite entre l'application

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Non, pas du tout. Le serveur à part est la solution à ton problème
    Pour le serveur dans une appli à part, OK pour la contrainte projet. Ce sera un thread.
    Plaçons-nous du côté utilisateur final. Il lance ton jeu, et choisis de démarrer une partie en réseau. Il va donc cliquer sur un bouton pour être serveur : le thread du serveur démarre. ensuite, il appelle un copain, lui transmet son IP+port et son copain lance aussi ton jeu et rentre l'IP+port serveur. Il ne cliquera donc pas sur le bouton de lancement du serveur.
    Maintenant, plaçons-nous côté code. Le serveur est réellement un thread à part du client. Le serveur n'a pas à savoir quel est le client local et quel est le client distant. Le serveur va simplement envoyer un message au client qui doit jouer et un autre message au client qui doit attendre. Le serveur va changer alternativement de client. Le client local se connecte par socket au serveur, comme s'il était distant.
    Tu dois simplement créer un protocole simple de communication client-serveur.
    Le gros avantage est que tu fais une découpe nette entre le code client et le code serveur et le code devient maintenable. De plus, la connexion entre un client et le serveur reste permanente : le code de communication est simplifié, la connexion socket se fait une et une seule fois.
    Je le dis et le répète : tu ne dois pas mélanger le code client et le code serveur
    ensuite, on peut imaginer que toutes les règles du jeu sont codées sur le serveur. C'est le serveur qui valide ou non un coup. Le client devient un simple afficheur graphique qui répond aux ordres du serveur.

  5. #5
    Membre à l'essai
    Inscrit en
    Mars 2008
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 27
    Points : 24
    Points
    24
    Par défaut
    Tu lance avec un des deux joueurs un serveur.

    Ensuite tu considère les deux joueurs comme clients.

    Le joueur qui a crée le serveur envoi quand même des messages réseaux au server en local .

    A chaque fois que quelqu'un joue, il envoie un message au serveur. Le serveur renvoie un message à tous les joueurs avec les données du coup ainsi que le joueur qui doit joueur le prochain coup.

    Chaque client reçoit ce message. et adapte son interface en fonction du dit message. Celui qui doit attendre, tu lui bloque l'accès aux fonctions pour faire un tour par exemple

  6. #6
    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
    ca m'a l'air de sacrement complexifier le problème!
    en effet mon appli n'est pas a proprement parler une appli client-serveur, ce n'est pas comme si plusieurs joueurs pouvaient joueur ensemble, la c'est clair qu' il faudrait un processus(thread,appli) dédié pour gérer les coups joués et les redistribués, ou si par exemple tous mes traitements seraient fait du coté serveur et que le client ne serait plus qu'un afficheur graphique, ce qui n'est pas le cas non plus.
    voila pourquoi je trouve que ca complexifie la communication:
    -ma solution
    j1 joue
    j1 execute et affiche son coup
    j1 envoie son coup a j2
    j2 recoie le coup
    j2 execute et affiche le coup
    j2 joue
    ...
    -solution client serveur
    j1 joue
    j1 envoie son coup au serveur
    le serveur renvoie le coup a j1 et j2
    j1 recoit le coup
    j1 execute et affiche le coup
    j2 recoit le coup
    j2 execute et affiche le coup
    j2 joue
    ...
    dans tous les cas:
    -les clients envoie des coups
    -les clients recoivent des coups
    mais dans la solution client-serveur, les coups transitent par un serveur, qui ne fait rien de special, ce qui fait une étape supplementaire

    il est clair que je suis d'accord avec vous pour ce qui concerne les application clients serveurs, mais ce n'est pas vraiment le cas-ici

    au passage j'ai réglé le problème pour lequel j'avais posté en mettant la reception du coup dans un thread, ca évite en plus de frizzer l'application qui attend que l'autre joueur joue

  7. #7
    Membre éprouvé
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Points : 1 078
    Points
    1 078
    Par défaut
    Dès que tu as une communication réseau, tu as forcément une relation de client/serveur. Donc pourquoi vouloir se voiler la face?

    Ce que t'as expliqué dinobogan est de loin la meilleure solution. Comme tu ne l'as jamais fait, tu peux avoir l'impression de complexifier les choses, mais en réalité, tout sera plus simple pour toi une fois en place.

  8. #8
    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
    je commence a rencontrer le probleme que vous essayez de me faire comprendre. a la fin de la partie chaque joueur doit afficher un rapport ou il y aura marqué le nombre de fois ou chaque joueur a demandé l'indication du meilleur coup. Avec ma solution j1 envoie a j2 qui attend et j2 envoie a j1 qui attend...ca fait un gros conflit réseau. avec une solution serveur chaque joueur envoie son nombre d'indication au serveur, le serveur une fois qu'il a tout reçue renvoie les 2 nombre a chaque client. c'est vrai que c'est beaucoup plus simple
    je vais mettre en place cette solution comme dinobogan le voyait
    je met pas encore résolue j'aurait peut-etre besoin de vous en cas de probleme

  9. #9
    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
    bon je viens de mettre en place mon serveur via un thread declenché chez le joueur qui initie la partie (au passage merci a gfx pour son tuto)
    c'est vrai que la gestion a l'ai beaucoup plus simple, en revanche j'ai un petit probleme en ce qui concerne la facon dont un client "connait" tous les autres client
    je m'explique, le thread du serveur principal est codé de cette facon
    a chaque nouvelle demande de connexion de la part d'un client un thread secondaire est créé qui s'occupe des données recues par ce 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
     try {
                serverSocket = new ServerSocket(7780);
            } catch (IOException ex) {
                finpartie=true;
            }
     
            while (!finpartie)
            {
                try
                {
                    Socket ts = serverSocket.accept();
                    thread_client tc = new thread_client(jeucourant, ts);
                    tc.start();
                }
                catch (Exception e)
                {
     
                }
            }
    les threads secondaire sont codés de cette facon, le probleme est que si je recois un coup recu d'un client, comment je connait l'ensemble des clients a qui envoyer le coup? en effet je ne peut envoyer les données recues qu'au client qui les a envoyés, je ne connait que le socket de ce client.
    une solution qui m'a effleurer l'esprit pour résoudre ce probleme est qu'a chaque nouvelle demande de connexion de la part d'un client, on envoie le socket a tous les threads secondaire qui les stockerais par exemple dans une liste de socket. ensuite lorsqu'un thread secondaire veut envoyer ce qu'il a recue a tous les clients il n'aura qu'a parcourir cette liste. Mais bon cette solution me semble bizarre, ca se trouve j'ai strictement rien compris au principe serveur/thread/socket, c'est pourquoi j'attend confirmation de votre part de ma solution et de mon code
    au passage, est-il nécessaire a chaque fois qu'on fait un input ou un output qu'on le ferme avant d'en faire un nouveau?
    autre chose, c'est un thread du coté de mes clients qui réceptionne les coups, sur quel port faut-il que je le mette? en effet j'aurais tendance a les mettre sur les port 7780 le meme que le serveur, mais cela ne va pas faire conflit réseau? (tous mes sockets serait sur le meme ports)
    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
    public thread_client(jeu j, Socket s)
        {
            jeucourant=j;
            socket = s;
        }
     
     
        @Override
        public void run()
        {
            try
            {
                while (!finpartie)
                {
                    input = new ObjectInputStream(socket.getInputStream());
                    Object obj=input.readObject();
                    if (obj instanceof classe.coup)
                    {
                        coup c = (coup)obj;
                        output = new ObjectOutputStream(socket.getOutputStream());
                        output.writeObject(c);
                        output.close();
                        ...
    merci d'avance pour vos réponses

  10. #10
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Citation Envoyé par bobby51 Voir le message
    en revanche j'ai un petit probleme en ce qui concerne la facon dont un client "connait" tous les autres client
    je m'explique, le thread du serveur principal est codé de cette facon
    a chaque nouvelle demande de connexion de la part d'un client un thread secondaire est créé qui s'occupe des données recues par ce client

    les threads secondaire sont codés de cette facon, le probleme est que si je recois un coup recu d'un client, comment je connait l'ensemble des clients a qui envoyer le coup? en effet je ne peut envoyer les données recues qu'au client qui les a envoyés, je ne connait que le socket de ce client.
    une solution qui m'a effleurer l'esprit pour résoudre ce probleme est qu'a chaque nouvelle demande de connexion de la part d'un client, on envoie le socket a tous les threads secondaire qui les stockerais par exemple dans une liste de socket. ensuite lorsqu'un thread secondaire veut envoyer ce qu'il a recue a tous les clients il n'aura qu'a parcourir cette liste. Mais bon cette solution me semble bizarre, ca se trouve j'ai strictement rien compris au principe serveur/thread/socket, c'est pourquoi j'attend confirmation de votre part de ma solution et de mon code
    C'est le serveur qui s'occupe de recevoir les données d'un client et de les redistribuer aux autres clients. C'est le serveur qui gère une liste de flux en écriture.
    Le serveur possède un thread par client, le thread est en attente de lecture. Lorsqu'une info est lue, cette info est traitée par le serveur. Selon le degré de connaissance du serveur (extrême minimum : il envoie à tous les clients ce qu'il vient de lire, extrême maximum : toutes les règles du jeu sont sur le serveur, il traite l'information et envoie une erreur au client si coup impossible ou envoie des infos uniquement aux clients concernés) des infos sont envoyées aux autres clients. Un client ne connait que sont serveur, il ne connait aucun autre client.

    au passage, est-il nécessaire a chaque fois qu'on fait un input ou un output qu'on le ferme avant d'en faire un nouveau?
    Surtout pas ! Sinon la socket va être fermée. La connexion doit restée en permanence ouverte. La connexion au serveur est faite une fois pour toute par le client.

    autre chose, c'est un thread du coté de mes clients qui réceptionne les coups, sur quel port faut-il que je le mette? en effet j'aurais tendance a les mettre sur les port 7780 le meme que le serveur, mais cela ne va pas faire conflit réseau? (tous mes sockets serait sur le meme ports)
    Je pense que tu n'as pas tout saisi
    Le client ouvre une socket sur le serveur avec une adresse IP et un port. Cette socket est en lecture/écriture. Le client démarre un thread d'écoute du socket, il attend en permanence et lit les informations qui viennent du serveur.

  11. #11
    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
    c'est bon j'ai mit en place la solution ca marche parfaitement. concernant mon inquiétude sur le port c'etait que mon socket coté client était constamment en attente de lecture et de temps en temps en écriture (lorque le client joue) mon inquiétude venait du cas ou il lit et ecrit en meme temps, bon ca a pas l'air de poser de problème
    merci a tous de m'avoir aider pour ce probleme, surtout a toi dinobogan, ca ma permis de bien comprendre le concept client/serveur
    le sujet est clos

  12. #12
    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
    Bonjour à tous !

    Je me permets de relancer le sujet étant donné que je rencontre la même genre de problème avec une interface graphique ne voulant pas se mettre à jour (même avec un repaint) et des communications réseaux (TCP).

    J'avais également implémenté le serveur dans le joueur qui lance la partie et ne l'avait pas différencié du client pour le même joueur. De là le problème de rafraichissement si j'ai bien suivi.

    Donc après lecture des différents posts je me suis lancé dans l'implémentation d'un serveur multithreads mais j'avoue que je bloque un peu...

    J'ai du mal avec le fait que les 2 sockets client-serveur (2 clients pour 1 serveur) soient ouvert en permanence et que lorsque le serveur reçoit un objet d'un des deux clients, il le renvoie à l'autre...

    bobby51, peux-tu me donner des détails quant à ton implémentation || quelques conseils pour me débloquer ?

    Merci d'avance.

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

Discussions similaires

  1. incrémentation non rafraichie
    Par youp_db dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 14/11/2006, 21h47
  2. Affichage non correct d'une image
    Par AnonCoder dans le forum Langage
    Réponses: 2
    Dernier message: 03/11/2006, 13h51
  3. Bug d'affichage non identifié. . .
    Par TheReturnOfMuton dans le forum Interfaces Graphiques en Java
    Réponses: 7
    Dernier message: 21/06/2006, 20h25
  4. [C#] Label non rafraichi
    Par BiM dans le forum ASP.NET
    Réponses: 19
    Dernier message: 07/04/2005, 16h00
  5. [JTable]cellules non rafraichies
    Par freudy dans le forum Composants
    Réponses: 3
    Dernier message: 02/07/2004, 16h03

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