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 :

[Socket] Erreur: NotSerializableException


Sujet :

Entrée/Sortie Java

  1. #1
    Membre éclairé Avatar de rvfranck
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    746
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 746
    Par défaut [Socket] Erreur: NotSerializableException
    Salut,

    je veux envoyer un objet sérialisé à travers une socket et j'ai l'exception suivante qui est lévée:
    NotSerializableException.
    en fait j'ai un serveur qui reçoit les connexions et range dans une hashtable ce que j'appelle les flux sortants:
    ObjectOutputStream (pour pouvoir renvoyer les messages aux clients).

    Ce que je ne comprends pas, c'est que quand je lance le premier client alors le programme s'exécute bien, je veux dire pas
    d'exeption quand j'execute un writeObject().
    lorsque je lance le deuxième client et que j'essaie de lui envoyer un objet (message) à partir de la socket qui existe
    entre le serveur et lui, là ça passe pas.
    Le premier client passe, les autres pas du tout. Je ne comprends pas

    le 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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
     
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.*;
     
    public class Server extends ServerSocket
    {
    	Hashtable userOnLine = new Hashtable(); // tous les clients connectés
    	static int port = 4444;
     
    	public Server(int port) throws Exception
    	{	
    		super(port);
     
    		try
    		{
    			System.out.println("Le serveur est lancee");
     
    			while(true)
    			{
    				Socket connexion = this.accept();
    				System.out.println("\nLe serveur a recu une nouvelle connexion");
    				new ThreadConnexion(connexion, userOnLine);
    			}
    		}
    		catch(Exception e)
    		{
    			System.err.println("Erreur du serveur (constructeur): " + e);
    		}
    	}
     
    	public static void main(String []arg) throws Exception
    	{
    		new Server(port);
    	}
    }
    la classe ThreadConnexion:

    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
    116
    117
    118
    119
    120
    121
    122
    123
     
     
    import java.net.Socket;
    import java.io.*;
    import java.util.*;
     
    public class ThreadConnexion extends Thread 
    {
     
    	Socket connexion;
    	Hashtable userOnLine;
     
    	ObjectInputStream FluxEntrant;
    	ObjectOutputStream FluxSortant; 
     
    	BufferedReader FluxSaisie = new BufferedReader(new InputStreamReader(
    									System.in)); // pour saisir
    	// le nom du client qui s'est connecté: bon c'est juste pour l'exemple
     
    	String pseudo;
     
    	public ThreadConnexion(Socket connexion, Hashtable uol)
    	{
    		try
    		{
    			setPseudo(); // saisir le pseudo du client
    			this.connexion = connexion;
    			this.userOnLine = uol;
     
    			this.FluxSortant = new ObjectOutputStream(connexion.getOutputStream());
    			this.FluxEntrant = new ObjectInputStream(connexion.getInputStream());
     
     
    			this.alerteConnexion();
    			this.start();
    		}
    		catch(Exception e)
    		{
    			System.err.println("Erreur (constructeur de threadconnexion): " + e);
    		}
    	}
     
    	public void run()
    	{
     
    		try
    		{
     
    			while(true)
    			{
    				Message objet = (Message) FluxEntrant.readObject();
     
    				String recepteur = objet.getRecepteur();
    				ObjectOutputStream fs = (ObjectOutputStream)userOnLine.get(recepteur);
    				fs.writeObject(objet);
    			}
    		}
    		catch(Exception e)
    		{
    			System.err.println("Erreur (run de threadconnexion): " + e);
    		}
    	}
     
     
    	public void alerteConnexion()
    	{
    		try
    		{
    			// informer les autres users d'une nouvelle connexion
    			alertAllUser();
     
    			// envoyer au nouveau connecté la liste des utilisateurs déjà connectés
    			// c'est ici que sa marche pas: l'instruction writeObject
    			FluxSortant.writeObject(new Message("serveur","liste connecte",null,null,userOnLine));
     
    			// ajout du nouvel utilisateur dans la tableau des utilisateurs connectés 
    			userOnLine.put(getPseudo(),FluxSortant);i++;
     
     
    			System.out.println("Nbre total de connecte: " + userOnLine.size());
    		}
    		catch(Exception e)
    		{
    			System.err.println("Erreur (alerteconnexion): " + e);
    		}
    	}
     
     
    	public void alertAllUser()
    	{
    		try
    		{
    			System.out.println("\nAvertissement de tous les users\n");
    			for(Enumeration e = userOnLine.elements(); e.hasMoreElements();)
    			{
    				ObjectOutputStream fs = (ObjectOutputStream) e.nextElement();
    				fs.writeObject(new Message("serveur","connexion",null,pseudo,null));
    			}
    		} 
    		catch(Exception e)
    		{
    			System.out.println("Erreur lors de l'avertissement de tous les users: " + e);
    		}
    	}
     
    	public void setPseudo()
    	{
    		System.out.print("Pseudo du nouveau connecté: ");
    		try
    		{
    			pseudo = FluxSaisie.readLine();
    		}
    		catch(Exception e)
    		{
    			System.out.println("Erreur de saisie");
    		}
    	}
     
    	public String getPseudo()
    	{
    		return pseudo;
    	}
    }

    voilà l'objet Message que je veux envoyer:

    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
     
     
    import java.io.Serializable;
    import java.util.*;
     
    public class Message implements Serializable
    {
    	private String expediteur = "";
    	private String message = "";
    	private String recepteur = "";	
    	private String information = "";
    	private Hashtable listeConnectes;
     
    	public Message(String ex, String mes, String rec, String info, Hashtable ht) 
    	{
    		this.expediteur = ex;
    		this.message = mes;
    		this.recepteur = rec;
    		this.information = info;
    		this.listeConnectes = ht;
    	}
     
    	public String getExpediteur() 
    	{
    		return expediteur;
    	}
     
    	public String getMessage() 
    	{
    		return message;
    	}
     
    	public String getRecepteur() 
    	{
    		return recepteur;
    	}
     
    	public String getInformation() 
    	{
    		return information;
    	}	
     
    	public Hashtable getListeConnectes() 
    	{
    		return listeConnectes;
    	}	
    }
    Le client ne fait pas grand chose, il reçoit les messages et me les affiche sur la console.
    Merci de m'aider.

  2. #2
    Membre éclairé Avatar de rvfranck
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    746
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 746
    Par défaut
    C'est encore moi. Cela peut il être du au fait que je veuille transmettre un objet qui contient une hashtable? si oui, pourquoi ça marche alors lorsque le premier client se connecte?

  3. #3
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    oui, d'après moi cela vient de la hashtable (ou bien de son contenu)...

    déclare-la "transient" pour qu'elle ne figure pas dans la forme sérialisée de ton instance

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private transient Hashtable listeConnectes;

  4. #4
    Membre éclairé Avatar de rvfranck
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    746
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 746
    Par défaut
    Merci.
    Lorsque j'ajoute transcient j'ai plus de message d'erreur mais la hashtable au niveau du client vaut null lorsque je fais ça.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    Message obj = (Message)FluxEntrant.readObject();
    if(obj.getListeConnectes()==null) 
      System.out.println(''La hastable est null'');
    else
      System.out.println(obj.getListeConnectes().size());
    Quelqu'unaurait il une autre methode pour que j'envoi la liste des connectés aux clients?

    Merci

  5. #5
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par rvfranck
    Lorsque j'ajoute transcient j'ai plus de message d'erreur mais la hashtable au niveau du client vaut null lorsque je fais ça.
    C'est normal puisque transient permet de ne pas sauvegarder l'attribut dans le flux...

    Citation Envoyé par rvfranck
    Quelqu'unaurait il une autre methode pour que j'envoi la liste des connectés aux clients?
    Hastable est bien sérializable, mais il faut que tous les éléments qu'elle contient le soit également...

    Maintenant je ne sais pas si la sérialisation est la meilleur solution car en cas de changement dans ta classe Message, il faudra que le serveur et les clients possèdent exactement la même version des classes...

    a++

  6. #6
    Membre éclairé Avatar de rvfranck
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    746
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 746
    Par défaut
    J'ai trouvé une solution: en fait le client à besoin de la liste des users connectés au chat qui correspond aux clés de la hashtable. Alors j'ai mis les clés dans un tableau de string et j'ai envoyé l'object message. Bien sur j'ai modifié dans l'objet message la hashtable par un tableau de String.

    Merci

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

Discussions similaires

  1. [Socket]Erreur de compilation
    Par elmodeno dans le forum C++
    Réponses: 11
    Dernier message: 10/02/2007, 22h16
  2. socket : erreur avec bind()
    Par horkets dans le forum Réseau
    Réponses: 11
    Dernier message: 30/10/2006, 11h47
  3. [socket] erreur accept
    Par CaptainChoc dans le forum Réseau
    Réponses: 3
    Dernier message: 28/12/2005, 11h32
  4. [Socket] erreur de connexion
    Par coachbob44 dans le forum C++
    Réponses: 4
    Dernier message: 03/03/2005, 17h14

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