在C#中将一个对象转换成字节数组,通过套接字发送,然后再将其转换回对象

6

我有一台服务器和一个客户端,它们之间会相互交换各种数据。最初,我采用了一种复杂的方法,逐个地将字节数组中的变量和字符串转换为它们应该是的类型。后来我发现可以把所有变量放进一个对象中,然后使用

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();
    }

使用以下方法将其转换回来

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;
    }

问题是,一旦我把这个字节数组发送到另一个应用程序,我就不能再使用这种方法将其转换回来,会出现错误“无法找到程序集 'test1s, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'。” test1s只是我为测试而创建的小型服务器程序的名称。显然,应用程序需要一些额外的信息才能将此数组转换回对象,所以我是否可以做到这一点,或者我解决问题的方法不正确?
我的目标是创建一个仅由几个变量和字符串组成的对象,将其转换为字节数组,发送到另一个应用程序,并将其转换回对象。这样,我就不必操作字节数组来提取所有的变量和字符串。
谢谢

如果我是你,我会使用调试器来尝试解决这个问题。除非你认为调试器是万恶之源。如果你不知道我的意思,请看看这个链接:http://stackoverflow.com/questions/602138/is-a-debugger-the-mother-of-all-evil - YWE
4个回答

8

有许多预制的序列化库可以帮助解决这个问题。BinaryFormatter在这里有一些(依我看来)不理想的特点-特别是它只能与两端具有相同(基本上是相同的)dll一起使用。

XmlSerializer, DataContractSerializer和JavaScriptSerializer是很好的基于文本的实现,只要两端有兼容的合同(相同的属性等-不一定是相同的类型/版本),就可以正常工作。

如果您需要中等带宽需求或更好的CPU性能,我建议使用protobuf-net(警告:我编写了它),这是一个快速的二进制序列化程序,可能会有所帮助。


4
如果通信双方都有对完全相同的程序集完全相同版本的程序集的引用,则此方法可行,这些程序集可以通过程序引用或在GAC中存储。
如果需要一种更容忍版本不匹配的机制,请考虑改用XMLSerializer(但请注意,如果版本不匹配,则字段/属性的添加/删除/更改可能导致不正确的行为)。
如果需要紧凑格式,您可以考虑查看Google Protocol Buffers

1
如果您想发送字符串列表(或字符串字典),那么这不是问题,只需发送字符串列表(或字典)。您的问题在于您试图发送其他项目无法识别的数据类型。您甚至不需要更改任何功能,只需要更改您发送的内容。或者,您可以从接收数据的程序中引用test1s。

0

编写自己的对象从/到字节转换器,而不是使用BinaryStream应该可以工作。

如果您坚持使用BinaryStream,请将此对象移动到其自己的程序集中,并将其添加到两侧作为引用。这样,.NET Framework应该能够对对象进行反序列化和序列化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接