Tcp socket + envoi d'objet

Blacknight91 Messages postés 77 Date d'inscription vendredi 26 mars 2004 Statut Membre Dernière intervention 24 avril 2007 - 10 sept. 2006 à 12:33
youcefsoft Messages postés 1 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 2 juin 2009 - 2 juin 2009 à 19:55
bonjour,

voilà je voudrais créer une connexion tcp client/serveur pour envoyer des données. Ces données sont dans des objets (une datatable par exemple). j'ai regardé sur le forum, il y en a qui parle de serialization d'objet pour permettre l'envoi de celui-ci, mais je ne comprends pas ce que c'est.

j'ai également vu des sources de connexions client/serveur tcp, mais à chaque fois les exemples ne sont faits qu'avec des envois de string.

Comment faire pour envoyer des objets comme une datatable ?

merci de m'expliquer la serialisation si celle-ci est obligatoire.

Blacknight91
http://blacknight91.free.fr/Flash_nouvelle/

11 réponses

aogie Messages postés 108 Date d'inscription vendredi 11 juillet 2003 Statut Membre Dernière intervention 27 novembre 2007
11 sept. 2006 à 10:51
Il existe plusieurs type de sérialisation : binaire, SOAP, XML.

Le but est identique : créer une représentation d'un objet, en vue de
le stocker ou de le transmettre. La désérialisation permet ensuite de
retrouver l'objet avec ses paramètres.

Il faut savoir que l'opération de sérialisation ne conserve que le type
et la valeur de chaque  variable privée (aucune prise en compte du
nom des méthodes par exemple).

Dans le cas d'une sérialisation binaire (par exemple) : tu devras créer
un flux (MemoryStream) et un formateur binaire (BinaryFormatter), puis
sérialiser ton objet vers le flux grâce à la méthode "Serialize" de ton
BinaryFormatter.

Pour utiliser un tableau d'octets, il ne reste plus qu'à copier le
contenu du flux vers un tableau d'octets de taille équivalente...


Cas particulier de la désérialisation :

Si cette opération est effectuée par le même projet, il n'y a aucun
souci. En revanche, si tu crées une classe permettant l'opération de
sérialisation/désérialisation entre deux projets différents. La
désérialisation échouera car l'en-tête (comportant les attributs de
l'Assembly) est différente.

Pour contourner le problème, il faut ajouter un Binder au
BinaryFormatter, pour contrôler la liaison de l'objet. Il a pour but le
renommage de l'en-tête avec les attributs de l'Assembly courante, juste
avant la tentative de désérialisation.

Celle-ci réussit de ce fait.

-- AOGie --
0
Blacknight91 Messages postés 77 Date d'inscription vendredi 26 mars 2004 Statut Membre Dernière intervention 24 avril 2007 1
13 sept. 2006 à 08:37
merci pour tes explications sur la serialization.
j'ai bien réussi a sérialiser et envoyer le flux d'octets, par contre comme tu l'as dit, à la désérialisation ca plante car les 2 projets sont différents. Peux tu m'en dire plus sur le Binder, comment l'utiliser ?
VS me dit que c'est une classe abstraite qui ne peut etre instancier.

Blacknight91
http://blacknight91.free.fr/Flash_nouvelle/
0
aogie Messages postés 108 Date d'inscription vendredi 11 juillet 2003 Statut Membre Dernière intervention 27 novembre 2007
14 sept. 2006 à 11:01
Exact, "SerializationBinder" est une classe abstraite.

Il faut créer une classe qui dérive de" SerializationBinder" et surcharger la méthode de liaison de type :

private class DeserializeBinder : SerializationBinder

{

    public override Type BindToType(string assemblyName, string typeName)

    {

          string currentAssemblyName = Assembly.GetExecutingAssembly().FullName;

          if (assemblyName != currentAssemblyName)

                assemblyName = currentAssemblyName;

          return Type.GetType(string.Format("{0}, {1}", typeName, assemblyName);

    }

}


Pour une désérialisation binaire, par exemple :


BinaryFormatter bf = new BinaryFormatter();

bf.Binder = new DeserializeBinder();

object o = bf.Deserialize(<stream>);

-- AOGie --
0
Blacknight91 Messages postés 77 Date d'inscription vendredi 26 mars 2004 Statut Membre Dernière intervention 24 avril 2007 1
14 sept. 2006 à 22:22
je viens de rajouter le code dans le projet ou je fais la deserialisation, mais j'ai une erreur qui se produit sur celle ci:
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll

Additional information: End of Stream encountered before parsing was completed

as tu une idée du pourquoi ?

Blacknight91
http://blacknight91.free.fr/Flash_nouvelle/
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
aogie Messages postés 108 Date d'inscription vendredi 11 juillet 2003 Statut Membre Dernière intervention 27 novembre 2007
15 sept. 2006 à 08:32
Tu as vraisemblablement une erreur dans le stream.

Voici un exemple avec sérialisation/désérialisation binaire :

Sérialisation avec un objet "obj" en entrée et un tableau d'octets en sortie :


MemoryStream m = new MemoryStream();

BinaryFormatter bf = new BinaryFormatter();

bf.Serialize(m, obj);

byte[] buffer = new byte[m.Length];

Array.Copy(m.GetBuffer(), buffer, buffer.Length);

m.Close();

return buffer;


Désérialisation avec un tableau d'octets "data" en entrée et un objet en sortie :


MemoryStream m = new MemoryStream(data);

BinaryFormatter bf = new BinaryFormatter();

bf.Binder = new DeserializeBinder();

object obj = bf.Deserialize(m);

m.Close();

return obj;


Ces exemples ne comportent aucune gestion d'erreur...

-- AOGie --
0
Blacknight91 Messages postés 77 Date d'inscription vendredi 26 mars 2004 Statut Membre Dernière intervention 24 avril 2007 1
15 sept. 2006 à 19:26
j'ai toujours la meme erreur malgré ton code donné.
j'ai meme fait le test dans un meme projet, executé 2 fois, (l'un qui serialize et envoi, l'autre qui récupère et deserialize), ils ont les meme assembly normalement ?

Blacknight91
http://blacknight91.free.fr/Flash_nouvelle/
0
aogie Messages postés 108 Date d'inscription vendredi 11 juillet 2003 Statut Membre Dernière intervention 27 novembre 2007
17 sept. 2006 à 10:48
Je ne vois pas d'où peut provenir l'erreur. Commence par essayer une sérialisation avec un objet très simple.
Cela fonctionne, car j'utilise également (avec gestion d'erreur). Ensuite, tu devas peut être te pencher du côté de l'objet que tu sérialises.
Cet objet et toutes les variables membres sont sérialisables ?
Y-a-t-il une opération effectuée (zippage ou cryptage) qui pourrait modifier la nature du flux ?

Bon courage.

-- AOGie --
0
Blacknight91 Messages postés 77 Date d'inscription vendredi 26 mars 2004 Statut Membre Dernière intervention 24 avril 2007 1
17 sept. 2006 à 11:32
est ce que les objets doivent dérivés de la classe ISerializable, ou une classe du meme genre ?
je fais ca sur des DataTable et DataSet

Blacknight91
http://blacknight91.free.fr/Flash_nouvelle/
0
aogie Messages postés 108 Date d'inscription vendredi 11 juillet 2003 Statut Membre Dernière intervention 27 novembre 2007
17 sept. 2006 à 13:04
Les objets doivent posséder l'attribut [Serializable] ou implémenter l'interface ISerializable (ce qui est le cas des deux classes DataTable et DataSet). Il se peut qu'un objet stocké dans un DataSet ne soit pas sérializable. Il me semblait que le Framework possède pourtant tout ce qu'il faut pour la consultation de base de données distantes et que la sérialisation personnelle n'était pas une obligation ?

-- AOGie --
0
cs_haouari Messages postés 1 Date d'inscription jeudi 7 août 2003 Statut Membre Dernière intervention 16 avril 2009
16 avril 2009 à 00:13
svp Aogie essaye  de faire un example telechargable .
0
youcefsoft Messages postés 1 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 2 juin 2009
2 juin 2009 à 19:55
youcefsoft
0