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 :

Envoyer un objet avec un socket


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 4
    Par défaut Envoyer un objet avec un socket
    Bonjour,

    Dans le cadre de mon programme, j'aimerais envoyer un objet par un socket. Mais pas uniquement une class.

    Le but, c'est d'envoyer ceci :
    INT32 : Code de l'objet
    INT32 : Taille de l'objet
    object : L'objet en lui-même

    Comment puis-je faire ça ?
    Je crois comprendre que mon erreur provient de l'envoi. Je dois avouer que je ne comprends pas tout à fait comment fonctionne les MemoryStream et les BinaryFormatter.
    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
    static public class ProtocolMech
    {
        static public ProtocolMessage GetMessage(Socket Src)
        {
            Int32 size;
            Int32 type;
            byte[] msg;
            if (Src.Available > 2 * sizeof(Int32))
            {
                msg = new byte[sizeof(Int32)];
                Src.Receive(msg, sizeof(Int32), SocketFlags.None);
                type = (Int32)BitConverter.ToUInt32(msg, 0);
     
                msg = new byte[sizeof(Int32)];
                Src.Receive(msg, sizeof(Int32), SocketFlags.None);
                size = (Int32)BitConverter.ToUInt32(msg, 0);
     
                msg = new byte[size];
                Src.Receive(msg, size, SocketFlags.None);
     
                return new ProtocolMessage(type, ByteArrayToObject(msg));
            }
            else
                return null;
        }
     
     
        static public void SendMessage(Int32 Code, object Obj, Socket Dest)
        {
     
            MemoryStream _MemoryStream = new MemoryStream();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter
                        = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
     
            byte[] objbuff = ObjectToByteArray(Obj);
            Int32 SizeOfObj = Convert.ToInt32(objbuff.Length);
     
            _BinaryFormatter.Serialize(_MemoryStream, Code);
            _BinaryFormatter.Serialize(_MemoryStream, SizeOfObj);
            _BinaryFormatter.Serialize(_MemoryStream, Obj);
     
            Dest.Send(_MemoryStream.ToArray(), SocketFlags.None);
        }
     
        static public object ByteArrayToObject(byte[] _ByteArray)
        {
            try
            {
                MemoryStream _MemoryStream = new MemoryStream(_ByteArray);
     
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter
                            = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                _MemoryStream.Position = 0;
     
                return _BinaryFormatter.Deserialize(_MemoryStream);
            }
            catch (Exception _Exception)
            {
                // Error
                throw (_Exception);
            }
        }
     
        static public byte[] ObjectToByteArray(object Obj)
        {
            try
            {
                MemoryStream _MemoryStream = new MemoryStream();
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter
                            = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                _BinaryFormatter.Serialize(_MemoryStream, Obj);
                return _MemoryStream.ToArray();
            }
            catch (Exception _Exception)
            {
                // Error
                throw (_Exception);
            }
        }
    }
    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Y'a t il un interet quelconque à utiliser les Sockets plutot qu'une couche de plus haut niveau (WCF) ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 4
    Par défaut
    Citation Envoyé par Nathanael Marchand Voir le message
    Y'a t il un interet quelconque à utiliser les Sockets plutot qu'une couche de plus haut niveau (WCF) ?
    Ouaip : Je ne connais rien en WCF.

    Et j'ai pigé comment marche le memory stream et le binary formatter. Ce problème est réglé... Maintenant, j'en ai un autre. Je n'arrive pas à caster mon objet désérialisé.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2010
    Messages : 4
    Par défaut
    Avec la nouvelle version de mon code, ça marche mieux. Tout est transmis. Le problème vient de la deserialisation.

    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
    static public class ProtocolMech
    {
        static public ProtocolMessage GetMessage(Socket Src)
        {
            Int32 size;
            Int32 type;
            byte[] msg;
            if (Src.Available > 2 * sizeof(Int32))
            {
                Console.WriteLine(Src.Available);
                msg = new byte[54];
                Src.Receive(msg, 54, SocketFlags.None); //54 = nombre de byte du int32
                type = (Int32)ByteArrayToObject(msg);
                Console.WriteLine("Av left : " + Src.Available);
     
     
                msg = new byte[54];
                Src.Receive(msg, 54, SocketFlags.None);
                size = (Int32)ByteArrayToObject(msg);
                Console.WriteLine("Av left 2 : " + Src.Available);
     
                msg = new byte[size];
                Src.Receive(msg, size, SocketFlags.None);
                Console.WriteLine("Av left final : " + Src.Available);
     
                return new ProtocolMessage(type, msg);
            }
            else
                return null;
        }
     
     
        static public void SendMessage(Int32 Code, object Obj, Socket Dest)
        {
     
            MemoryStream _MemoryStream = new MemoryStream();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter
                        = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
     
            byte[] objbuff = ObjectToByteArray(Obj);
            byte[] sizebuff = ObjectToByteArray((Int32)objbuff.Length);
            byte[] codebuff = ObjectToByteArray(Code);
     
            byte[] buffTotal = new byte[objbuff.Length + sizebuff.Length + codebuff.Length];
            Buffer.BlockCopy(codebuff, 0, buffTotal, 0, codebuff.Length);
            Buffer.BlockCopy(sizebuff, 0, buffTotal, codebuff.Length, sizebuff.Length);
            Buffer.BlockCopy(codebuff, 0, buffTotal, codebuff.Length + sizebuff.Length, codebuff.Length);
            Dest.Send(buffTotal, SocketFlags.None);
        }
     
        static public object ByteArrayToObject(byte[] _ByteArray)
        {
            try
            {
                MemoryStream _MemoryStream = new MemoryStream(_ByteArray);
     
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter
                            = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                _MemoryStream.Position = 0;
     
                return _BinaryFormatter.Deserialize(_MemoryStream);
            }
            catch (Exception _Exception)
            {
                // Error
                throw (_Exception);
            }
        }
     
        static public byte[] ObjectToByteArray(object Obj)
        {
            try
            {
                MemoryStream _MemoryStream = new MemoryStream();
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _BinaryFormatter
                            = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                _BinaryFormatter.Serialize(_MemoryStream, Obj);
                return _MemoryStream.ToArray();
            }
            catch (Exception _Exception)
            {
                // Error
                throw (_Exception);
            }
        }
    }
     
    public class ProtocolMessage
    {
        public int Code {set; get;}
        public byte[] Object{get; set;}
     
        public ProtocolMessage(int Code, byte[] Obj)
        {
            this.Code = Code;
            this.Object = Obj;
        }
    }
    Quand j'invoque ma fonction de deserialisation comme ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Auth = (AuthContent)Protocol.ProtocolMech.ByteArrayToObject(msg.Object);
    Il me sort :
    Impossible d'effectuer un cast d'un objet de type 'System.Int32' en type 'DataType.AuthContent'.
    D'où est-ce que ça peut venir ? Je vérifier en debug : Il a bien les bonnes valeurs dans le MS.

  5. #5
    Membre émérite Avatar de NicoL__
    Homme Profil pro
    Architecte
    Inscrit en
    Janvier 2011
    Messages
    399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Janvier 2011
    Messages : 399
    Par défaut
    J'ai hésité à répondre à ce message... je réitère le conseil de Nathanael. Ou bien code en C ça évitera qu'on te donne ce genre de conseil. Mais sinon ça peut évidement fonctionner, mais j'avoue ne pas avoir eu le courage de décrypter tout ton code.
    Un indice, quand tu serialise un objet (une référence) tu sérialises par uniquement le contenu de l'objet mais son "pointeur aussi" la preuve un int32 prend 54 bytes donc il faut partager les définitions de tes classes du serveur au client.
    En suite l'objet AuthContent je ne le vois jamais instancier... donc c'est pas ça que tu envoies.
    C quoi l'erreur détaillée ?

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    pourquoi utiliser wcf qui permet de transférer des instances de classes quand on peut tout coder soi même avec une classe de bas niveau
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

Discussions similaires

  1. Envoyer un objet avec un Intent
    Par glycerine dans le forum Android
    Réponses: 5
    Dernier message: 27/05/2011, 10h21
  2. Envoi d'objet avec une socket
    Par HamzuS The Great dans le forum VB.NET
    Réponses: 4
    Dernier message: 06/09/2009, 15h09
  3. pb de récupérer un objet avec socket en java
    Par rhifay dans le forum Linux
    Réponses: 0
    Dernier message: 19/07/2008, 11h56
  4. envoyer un Objet en utilisant les sockets
    Par g.amine dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 02/02/2008, 08h56
  5. Envoyer et recuperer des buffers avec les Socket
    Par kaderscream dans le forum C++Builder
    Réponses: 2
    Dernier message: 19/08/2006, 11h44

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