[Erreur réseau] Mon client ne reçoit pas les infos

Résolu/Fermé
Sblerky - 11 avril 2018 à 11:26
 Sblerky - 11 avril 2018 à 13:40
Bonjour,

Je suis actuellement en train de développer un Frogger en Java et je dois implémenter du multijoueur dans le projet. J'ai donc une classe Serveur qui se lance quand je décide d'héberger une partie, elle peut accueillir plusieurs Connexion, une pour chaque Client. Et j'ai une classe Client pour quand je veux rejoindre une partie. Quand je suis un Client, je souhaite récupérer toutes les informations concernant le jeux (emplacement des plateformes, des autres joueurs etc...) via un Paquet que le Serveur m'envoie. Et du côté du Serveur, je me contente de récupérer les positions de tous les clients que je stocke dans un tableau puis je renvoie aux clients le Paquet contenant toutes les infos nécessaires. Le problème est le suivant, du côté du Serveur, quand le client bouge, la position change et tout marche niquel! Mais en ce qui concerne le Client, j'ai l'impression que le paquet ne se met jamais à jour...

Voici les portions de code annotées qui posent problème :
//ici nous sommes dans le run d'une connexion
//donc ce que le Serveur envoie aux clients
	@Override
	public void run(){
		Position requete= new Position(0,0);
                Object recu=null;
                try {
                    out.writeObject(id);
                } catch (IOException ex) {
                    Logger.getLogger(Connexion.class.getName()).log(Level.SEVERE, null, ex);
                }
		try{
			
			while(requete.getX()>=0){ 
                            
                            //on lit la position du client à qu appartient la connexion
                            
                            try {
                            recu=in.readObject();
                            } catch (ClassNotFoundException ex) {
                                Logger.getLogger(Connexion.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            requete=(Position)recu;
                            Serveur.ptab[id]=requete; //on la stocke dans le tableaux regroupant toutes les positions des joueurs
                            
				//la on envoie la position des plateformes plus celle des autres joueurs à tout le monde via le Paquet
				for(int i=0; i<Serveur.id; i++){
					if(Serveur.tab[i]!=null){
                                                //le print est un test pour vérifier que le Paquet se met bien à jour
                                                System.out.println(""+id+" "+Serveur.p1.getTabposOb()[0].getX()+" "+Serveur.ptab[id].getX());
                                                //et donc ce serait à ce niveau qu'il y aurait un problème
                                                Serveur.tab[id].writeObject(Serveur.p1);
                                                Serveur.tab[id].flush();
                                                				
					}
				}
		
			}
			connexion.close();
		}
		catch(IOException e){System.err.println(e);}
	}


//et voici la portion de code du Client qui écoute en permanence le réseau
		while(run){
                    //on envoie au serveur la position du client
                    try {                        
                        sleep(10);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    try {
                        out.writeObject(posj);
                        out.flush();                   
                    } catch (IOException ex) {
                        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                    }                
                    
                    
                    //et ensuite on recupere  le paquet du serveur (qui nous servira à gérer les déplacements des plateformes pour que ce soit 
                    //synchro chez tout le monde)
                    try {                
                        recu=in.readObject();
                    } catch (IOException | ClassNotFoundException ex) {
                        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    this.pin=(Paquet)recu;
                    System.out.println(""+id+" "+pin.getTabposOb()[0].getX()+" "+k);
} 


Le problème vient donc du fait que côté Client, on à l'impression que le Paquet est reçu une seule fois puis ne change plus alors que quand on teste du côté Serveur, les valeurs se mettent bien à jour. De plus, j'ai essayé de faire passer autre chose qu'un Paquet (un entier k qui augmentait avec le temps) et là, le code fonctionnait correctement...

Ma classe Paquet est sérialisable, et je ne comprends vraiment pas d'où peut venir ce problème...

Si vous avez besoin d'autres infos n'hésitez pas à me demander et merci d'avance pour l'aide que vous pourrez m'apporter.





1 réponse

KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
11 avril 2018 à 12:02
Bonjour,

Je n'ai pas tout regardé en détail, mais pourquoi tu fermes la connexion (ligne 39) ?

Remarque : il y a des technologies plus faciles à utiliser que les ObjectInput/OutputStream pour faire une application client/serveur, dans la "vraie vie" d'un développeur ce n'est clairement pas ce que l'on utiliserait.
0
Quand on arrive à cette ligne, c'est que le programme sera fini (j'enverrais une position négative pour notifier le serveur et cela fermera le socket).
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015 > Sblerky
11 avril 2018 à 13:36
En regardant un peu plus dans le détail, le serveur reçoit 1 position d'un client et la renvoie à N clients, et ce pour chacune des N connexions, donc le client ne va pas seulement recevoir 1 réponse initiée par sa requête, mais il va aussi recevoir toutes les réponses initiées par les requêtes des autres clients (plus ou moins N réponses) donc ta lecture va être incomplète et le serveur va bloquer.

Il faudrait que tu décorrèles les envois d'informations d'une part et la réception d'informations d'autre part dans deux canaux de communications distincts.
Tu dois éviter les alternances read/write/read/write, mais aboutir à des séquences indépendantes read/read/read et write/write/write.
0
J'ai trouvé le problème en fait il fallait utiliser WriteUnshared() au lieu de WriteObject() puis utiliser reset() au lieu de flush() car le flux pointait vers l'ancien objet à chaque fois sans l'actualiser. Merci de ta réponse je vais aussi essayer de mettre ça en place pour m'éviter de futurs problèmes.
0