2010-11-14 4 views
6

J'ai donc un serveur et un client qui communiquent diverses données en arrière et en quatrième. Initialement, j'avais une méthode compliquée qui traversait le tableau d'octets et convertissait toutes ses variables et chaînes, une par une, en ce qu'elles étaient supposées être. J'ai appris que je pouvais mettre toutes les variables dans un objet et le convertir en un tableau d'octets en utilisantConvertir un objet en un tableau d'octets en C#, l'envoyer sur un socket, puis le convertir en objet

private static byte[] ObjectToByteArray2(Object obj) 
    { 
     if (obj == null) 
      return null; 
     BinaryFormatter bf = new BinaryFormatter(); 
     MemoryStream ms = new MemoryStream(); 
     bf.Serialize(ms, obj); 
     return ms.ToArray(); 
    } 

Et reconvertir en utilisant

private static Object ByteArrayToObject(byte[] arrBytes) 
    { 
     MemoryStream memStream = new MemoryStream(); 
     BinaryFormatter binForm = new BinaryFormatter(); 
     memStream.Write(arrBytes, 0, arrBytes.Length); 
     memStream.Seek(0, SeekOrigin.Begin); 
     Object obj = (Object)binForm.Deserialize(memStream); 
     return obj; 
    } 

Le problème est, une fois que je vous envoie ce tableau d'octets à travers le réseau à une autre application, je ne peux pas simplement utiliser cette méthode pour le convertir en retour, je reçois l'erreur "Impossible de trouver l'assemblage 'test1s, Version = 1.0.0.0, Culture = neutre, PublicKeyToken = null'." test1s est juste le nom du petit programme serveur que j'ai fait pour jouer avec ça. Évidemment, l'application a besoin d'informations supplémentaires pour convertir ce tableau en un objet, donc est-ce que je peux le faire, ou est-ce que je vais à propos du problème? Ce que je veux accomplir ici est d'avoir un objet de rien, mais plusieurs variables et chaînes, le convertir en un tableau d'octets, l'envoyer à une autre application, et le convertir dans l'objet. De cette façon, je n'ai pas besoin de jouer avec le tableau d'octets pour extraire toutes mes variables et chaînes.

Merci

+0

Si j'étais vous, j'utiliserais un débogueur pour essayer de comprendre celui-ci. Sauf si vous croyez qu'un débogueur est la mère de tous les maux. Si vous ne savez pas ce que je veux dire, prenez un chargement de ceci: http://stackoverflow.com/questions/602138/is-a-debugger-the-mother-of-all-evil – YWE

Répondre

8

Il existe une myriade de bibliothèques de sérialisation pré-roulées qui vous aideront ici. BinaryFormatter a quelques caractéristiques indésirables (IMO) ici - en particulier, il ne fonctionnera qu'avec la même DLL (à peu près la même chose) aux deux extrémités.

XmlSerializer, DataContractSerializer et JavaScriptSerializer sont bonnes implémentations basées sur des textes, et fonctionnent bien avec un contrat compatible aux deux extrémités (mêmes propriétés etc - pas nécessairement le même type/version).

Si vous avez des besoins modérés en bande passante, ou si vous avez besoin de meilleures performances du processeur, je recommanderais protobuf-net (caveat: je l'ai écrit) qui est un sérialiseur binaire rapide qui peut aider. Ecrivez votre propre objet de/à octets convertisseur au lieu d'utiliser BinaryStream devrait fonctionner.

4

Cela fonctionnera si les deux côtés du canal de communication ont une référence à exactement le même ensemble et exactement la même version de cette assemblée, soit référencé du programme en quelque sorte ou vivant dans la GAC. Si vous voulez un mécanisme plus tolérant des discordances de version, pensez à utiliser XMLSerializer à la place (mais notez que l'ajout/suppression/changements dans les champs/propriétés peut entraîner un comportement incorrect si les versions ne correspondent pas). Si un format compact est requis, vous pouvez envisager d'examiner Google Protocol Buffers.

1

Si l'envoi d'une liste de chaînes (ou d'un dict de chaînes) est ce que vous voulez que ce ne soit pas un problème, il suffit d'envoyer une liste (ou dict) de chaînes. Votre problème vient parce que vous essayez d'envoyer un type de données que l'autre projet ne reconnaît pas. Vous n'avez même pas besoin de changer vos fonctions, vous avez juste besoin de changer ce que vous envoyez. Vous pouvez également référencer test1s du programme qui reçoit les données.

0

Si vous insistez, déplacez cet objet vers son propre assemblage et ajoutez-le aux deux côtés comme référence. De cette façon, .NET Framework devrait pouvoir dé/sérialiser l'objet.

Questions connexes