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

C# Discussion :

Objets et TcpClient


Sujet :

C#

  1. #1
    Membre éclairé Avatar de PoZZyX
    Inscrit en
    Août 2005
    Messages
    426
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 426
    Par défaut Objets et TcpClient
    Bonjour à toutes et à tous

    J'essaie d'envoyer grâce à TcpClient un objet en l'ayant d'abord sérialisé. Lorsque j'essaie de le recevoir, je ne sais pas vraiment comment procéder.

    J'en suis plus ou moins la :
    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
     
            public void ReceiveData()
            {
                while (true)
                {
                    if (stream.CanRead)
                    {
                        byte[] buffer = new byte[1024];
                        int numberByteRead = 0;
     
                        do
                        {
                            numberByteRead = stream.Read(buffer, 0, buffer.Length);
                        }
                        while (stream.DataAvailable);
                    }
                }
            }
    Ma question c'est essentiellement au niveau du buffer, comment connaître sa taille ? comment savoir combien de byte est-ce que je vais recevoir ? sinon comment concaténer mes bytes reçus pour finalement pouvoir déserialiser l'objet (qui fait plus que 1024 bytes) ?

    Merci d'avance pour votre aide !!!

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    La taille du buffer n'est pas importante. Ce buffer sert à la lecture des données que l'on va recevoir. Plus il est grand, moins il y aura de tour de boucle, mais ce n'est pas très important au final (il me semble en tout cas).

    Pour la concaténation, tu peux écrire dans un MemoryStream au fur et à mesure que tu reçois les données.

  3. #3
    Membre éclairé Avatar de PoZZyX
    Inscrit en
    Août 2005
    Messages
    426
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 426
    Par défaut
    Merci pour ton aide, mais j'ai un autre problème maintenant. Mon code coté serveur étant :
    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
     
    while (true)
                {
                    if (stream.CanRead)
                    {
                        byte[] buffer = new byte[1024];
                        int numberByteRead = 0;
                        mem = new MemoryStream();
                        while (stream.DataAvailable)
                        {
                            numberByteRead = stream.Read(buffer, 0, buffer.Length);
                            //mem.Write(buffer, (int)mem.Length, numberByteRead);
                            mem.Write(buffer, 0, numberByteRead);
                        }
                        if (mem.Length > 0)
                        {
                            Object o = SerializationTools.Deserialize(mem.GetBuffer());
                            if (o.GetType() == tankInformation.GetType())
                            {
                                lock (mutexTankInformation)
                                {
                                    this.tankInformation = (TankInformation)o;
                                }
                                serv.AddTankToUpdate(this.id);
                                Console.WriteLine("Server\tX : " + tankInformation.GetX() + " --- Y : " + tankInformation.GetY());
                            }
                        }
                    }
                }
    et coté client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    while (true)
                    {
                        //System.Threading.Thread.Sleep(1000);
                        lock (mutexTankInformation)
                        {
                            tankInformation.SetX(tankInformation.GetX() + 10);
                            tankInformation.SetY(tankInformation.GetY() + 5);
                        }
                        byte[] buffer = SerializationTools.Serialize(tankInformation);
                        stream.Write(buffer, 0, buffer.Length);
                    }
    Mon problème étant que j'ai l'impression que je n'arrive pas a séparer les paquets coté serveur. Normalement j'envoie des objets sérialisés d'environ 130 bytes, ce qui fonctionne très bien si j'envoie mon paquet chaque seconde avec un sleep.
    Mais si j'enlève mon sleep (pour avoir un pseudo temps réel), quand j'essaie de déserialiser mes données reçus, ça plante car mon memorystream est contient > 20000 bytes. Donc je pense il lit tout une série d'objets sérialisés avant de les désérialiser.

    Comment faire pour éviter ce problème ?

    Merci encore pour votre aide !!!

  4. #4
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Côté client tu écris sans arrêt des données (while(true)). Résultat côté serveur stream.DataAvailable sera toujours vrai. C'est pour ça que l'ajout de la pause permet le traitement côté serveur : le temps que le serveur finisse de lire, le client n'aura rien envoyé et on ne repartira pas dans la boucle.

    Teste, côté serveur, sur la longueur des données reçues. Si cette longueur est inférieure à la taille du buffer, alors tu as lu toutes les données possible pour l'envoi en cours.

    Quelque chose dans ce genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while (true)
    {
        numberByteRead = stream.Read(buffer, 0, buffer.Length);
        // A voir si Write déclenche une exception si on spécifie une longueur de données égale à 0.
        // A ce moment décommenter la ligne suivante.
        // if (numberByteRead == 0) { break; }
        mem.Write(buffer, 0, numberByteRead);
        if (numberByteRead < buffer.Length) { break; }
    }

Discussions similaires

  1. Envoie d'un objet sérialisé via un TCPClient
    Par mimosa803 dans le forum C#
    Réponses: 14
    Dernier message: 08/04/2009, 00h19
  2. codage objet
    Par charly dans le forum Algorithmes et structures de données
    Réponses: 18
    Dernier message: 22/08/2002, 16h49
  3. Importer des objets de 3dsMax
    Par Anonymous dans le forum OpenGL
    Réponses: 3
    Dernier message: 06/05/2002, 13h53
  4. Peux t'on créer une copie locale de l'objet partagé?
    Par Anonymous dans le forum CORBA
    Réponses: 8
    Dernier message: 16/04/2002, 16h20
  5. [Kylix] Erreur objet
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h41

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