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 :

Problème de transmission de données via socket


Sujet :

Entrée/Sortie Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2017
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Problème de transmission de données via socket
    Bonjour,

    Dans le cadre d'un projet en informatique en première année d'école d'ingénieur, je suis en train de réaliser une bataille navale en Java (pour le moment sur console). Le principe est simple : chaque joueur génére sa grille sous forme d'un objet Grille implémentant la classe Serializable qui contient toutes les informations sur les bateaux de chaque joueur. J'envoie cette grille au serveur une fois qu'elle est définie et le jeu des joueurs commence au tour par tour. Le premier tour du joueur 1 fonctionne correctement, mais une fois le tour du joueur 2 passé, j'ai l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Exception in thread "Thread-2" java.lang.InternalError
            at java.io.ObjectInputStream.readHandle(Unknown Source)
            at java.io.ObjectInputStream.readObject0(Unknown Source)
            at java.io.ObjectInputStream.readObject(Unknown Source)
            at Service.run(Service.java:40)
    java.io.StreamCorruptedException: invalid handle value: 007DFFFF
            at java.io.ObjectInputStream.readHandle(Unknown Source)
            at java.io.ObjectInputStream.readObject0(Unknown Source)
            at java.io.ObjectInputStream.readObject(Unknown Source)
            at Serveur.run(Serveur.java:55)
    Cela fait un sacré moment que je me penche sur le problème mais je n'ai toujours pas réussi à trouver la source du problème... Quelques tests plus tard, j'ai constaté un autre problème : lorsque le joueur 1 définit ses bateaux en premier et que le joueur 2 les définit ensuite, après le premier tour le jeu plante immédiatement avec l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    java.io.StreamCorruptedException: invalid handle value: 00000002
    	at java.io.ObjectInputStream.readHandle(Unknown Source)
    	at java.io.ObjectInputStream.readObject0(Unknown Source)
    	at java.io.ObjectInputStream.readObject(Unknown Source)
    	at Serveur.run(Serveur.java:38)
    java.io.StreamCorruptedException: invalid handle value: 00000002
    	at java.io.ObjectInputStream.readHandle(Unknown Source)
    	at java.io.ObjectInputStream.readObject0(Unknown Source)
    	at java.io.ObjectInputStream.readObject(Unknown Source)
    	at Service.run(Service.java:34)
    Si jamais le joueur 2 les définit en premier et ensuite le joueur 1 les définit, le tour 1 fonctionne mais le tour 2 (celui du joueur 2 donc) fait planter l'application à la fin de celui-ci avec l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Exception in thread "Thread-0" Exception in thread "Thread-2" java.lang.ClassCastException: java.io.ObjectStreamClass cannot be cast to Grille
    	at Serveur.run(Serveur.java:53)
    java.lang.InternalError
    	at java.io.ObjectInputStream.readHandle(Unknown Source)
    	at java.io.ObjectInputStream.readObject0(Unknown Source)
    	at java.io.ObjectInputStream.readObject(Unknown Source)
    	at Service.run(Service.java:39)

    J'espère que vous pourrez m'aider ! N'hésitez pas à me demander des informations complémentaires (ou à rectifier quelque chose d'aberrant, je ne demande qu'à apprendre). Voici les classes Serveur et Service que j'utilise :

    Serveur.java

    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
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
     
    public class Serveur extends Thread {
    	private int nbClients = 0;
    	public static boolean FIN = false;
    	public static int TOUR = 1;
    	public static int COMPTEUR = 0;
    	public static Grille grille1;
    	public static Grille grille2;
    	public static Service[] clients;
    	@Override
    	public void run() {
    		try {
    			this.clients = new Service[2];
    			ServerSocket ss=new ServerSocket(27190);
    			System.out.println("Le serveur est lancé sur le port 27190.");
    			System.out.println("En attente de connexions...");
    			while(!FIN){
    				while (nbClients != 2) {
    					Socket s=ss.accept();
    					this.clients[nbClients] = new Service(s,(nbClients+1));
    					this.clients[nbClients].start();
    					nbClients++;
    				} if (nbClients == 2) {
    					if (this.COMPTEUR == 2) {
    						System.out.println("Les deux grilles ont été reçues. Début du jeu.");
    						while (!FIN) {
    							System.out.print("Envoi des grilles... ");
    							this.clients[0].oos.writeObject(this.TOUR);
    							this.clients[1].oos.writeObject(this.TOUR);
    							System.out.println("terminé !");
    							if (this.TOUR == 1) {
    								System.out.println("Début du tour du joueur 1");
    								this.clients[0].oos.writeObject(this.grille2);
    								System.out.println("Grille envoyée au joueur 1. En attente du joueur 1...");
    								this.grille2 = (Grille) this.clients[0].ois.readObject();
    								System.out.println("Tour du joueur 1 terminé.");
    								System.out.println("Grille actuelle :");
    								this.grille2.afficherGrille();
    								this.FIN = Serveur.grille2.jeuTermine();
    								System.out.println("Fin du jeu :"+this.FIN);
    								if (!Serveur.FIN) {
    									this.TOUR = 2;
    								} this.clients[0].oos.writeObject(this.FIN);
    							} else if (this.TOUR == 2) {
    								System.out.println("Début du tour du joueur 2");
    								this.clients[1].oos.writeObject(this.grille1);
    								System.out.println("Grille envoyée au joueur 2. En attente du joueur 2...");
    								this.grille2 = (Grille) this.clients[1].ois.readObject();
    								System.out.println("Tour du joueur 2 terminé.");
    								System.out.println("Grille actuelle :");
    								this.grille1.afficherGrille();
    								this.FIN = Serveur.grille2.jeuTermine();
    								System.out.println("Fin du jeu :"+this.FIN);
    								this.TOUR = 1;
    								this.clients[1].oos.writeObject(this.FIN);
    							}
    						}
    					} else {
    						Thread.sleep(2000);
    						System.out.println("En attente de l'envoi des grilles...");
    					}
    				}
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args) {
    		new Serveur().start();
    	}
     
    }
    Service.java

    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
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    import java.net.SocketException;
     
    public class Service extends Thread{
    	private Socket socket;
    	private int numClient;
    	public ObjectInputStream ois;
    	public ObjectOutputStream oos;
    	public Service(Socket socket, int numClient) {
    		super();
    		this.socket = socket;
    		this.numClient = numClient;
    		try {
    			this.ois = new ObjectInputStream(this.socket.getInputStream());
    			this.oos = new ObjectOutputStream(this.socket.getOutputStream());
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     
    	@Override
    	public void run() {
    		try {
    			oos.writeObject(this.numClient);
    			System.out.println("Connexion du client n° "+this.numClient);
    			System.out.println("IP : "+this.socket.getRemoteSocketAddress());
    			while(Serveur.COMPTEUR < 2){
    				if (this.numClient == 1) {
    					Serveur.grille1 = (Grille) ois.readObject();
    					System.out.println("Grille du joueur 1 :");
    					Serveur.COMPTEUR++;
    					Serveur.grille1.afficherGrille();
    				} else if (this.numClient == 2) {
    					Serveur.grille2 = (Grille) ois.readObject();
    					System.out.println("Grille du joueur 2 :");
    					Serveur.COMPTEUR++;
    					Serveur.grille2.afficherGrille();
    				}
    			} if (Serveur.COMPTEUR == 2) {
    				System.out.println("Les grilles ont toutes été définies.");
    				if (Serveur.FIN) {
    					System.out.println("Fin du jeu !");
    					this.interrupt();
    				} else {
    					this.sleep(5000);
    				}
    			}
    		} catch (SocketException e) {
    			System.out.println("Le joueur n°"+this.numClient+" s'est déconnecté du serveur.");
    		} catch (IOException | ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     
    }
    P.S : la gestion du jeu quand il n'est pas terminé n'est pas encore faite, j'en suis tout à fait conscient, mais ce n'est pas la priorité pour le moment.

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 104
    Points : 140
    Points
    140
    Par défaut
    Bonjour,
    C'est très probablement un problème de multi-threading.
    Par exemple, le thread Serveur et le thread Service d'un joueur accèdent tous deux aux mêmes objets, par exemple à ois.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2017
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Bonsoir,

    Merci pour ta réponse. Du coup, est-ce que je dois ajouter des méthodes pour lire ou écrire les grilles de manière synchronisée, de ce style là ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public Grille readGrille() {
    	Grille grille = new Grille(10, new char[10][10], 5, new Bateau[5], 0);
    	synchronized (this.ois) {
    		while (grille.getBateaux()[0] == null) {
    			try {
    				grille = (Grille) this.ois.readObject();
    			} catch (IOException | ClassNotFoundException e) {
    				// TODO Auto-generated catch block
    				//e.printStackTrace();
    			}
    		} 
    	} return grille;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public void writeSynchronizedObject (Object objet) {
    	synchronized (this) {
    		try {
    			this.oos.writeObject(objet);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    Ou alors comment est-ce que je dois procéder ?

    EDIT : J'ai réussi à régler le problème ! Merci encore pour ton aide, tu m'as été d'une aide précieuse !

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

Discussions similaires

  1. [Axis2]Problème de transmission d'objets via un web services
    Par Martin22 dans le forum Services Web
    Réponses: 2
    Dernier message: 24/08/2009, 18h38
  2. Problème de transmission de données AS2 <=> PHP
    Par Sh1v3r dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 01/05/2009, 17h07
  3. Réponses: 0
    Dernier message: 06/03/2009, 22h31
  4. échange donnée via Socket
    Par jaussiba dans le forum Langage
    Réponses: 9
    Dernier message: 03/06/2008, 12h17
  5. Envoi de données via socket
    Par Popeye63 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 17/10/2007, 14h05

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