代码之家  ›  专栏  ›  技术社区  ›  cost

在C#中将对象转换为字节数组,通过套接字发送,然后转换回对象

  •  6
  • cost  · 技术社区  · 14 年前

    所以我有一个服务器和一个客户机,可以将各种数据传回给第四方。最初,我有一个复杂的方法,它遍历字节数组,并将其所有变量和字符串逐个转换为它们应该是的值。我学会了将所有变量放入一个对象中,并使用

    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,Culture=neutral,PublicKeyToken=null“。”test1s只是我用来玩这个的小服务器程序的名称。显然,应用程序需要一些额外的信息来将这个数组转换回一个对象,那么有什么方法可以做到这一点,还是我做错了?

    在这里,我要完成的是让一个对象只包含几个变量和字符串,将其转换为一个字节数组,将其发送到另一个应用程序,并将其转换回该对象。这样我就不必使用字节数组来提取所有变量和字符串。

    谢谢

    4 回复  |  直到 14 年前
        1
  •  8
  •   Marc Gravell    14 年前

    有无数的预滚序列化库可以在这里提供帮助。BinaryFormatter在这里有一些(IMO)不受欢迎的特性—特别是它只能在两端使用完全相同的(嗯,差不多)dll。

    XmlSerializer、DataContractSerializer和JavaScriptSerializer是很好的基于文本的实现,在兼容的 合同 两端(相同的属性等-不一定是相同的类型/版本)。

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

        2
  •  4
  •   cdhowie    14 年前

    如果通信信道的两边都有 确切地 相同的程序集和 完全相同版本的程序集 ,或者以某种方式从程序中引用,或者住在GAC中。

    如果您想要一种机制更能容忍版本不匹配,请考虑使用 XMLSerializer 相反(但请注意,如果版本不匹配,字段/属性中的添加/删除/更改可能会导致不正确的行为)。

    如果需要压缩格式,可以考虑查看 Google Protocol Buffers .

        3
  •  1
  •   Alxandr    14 年前

    如果发送字符串列表(或字符串的dict)是您想要的,那没问题,只需发送字符串列表(或dict)。您的问题是因为您试图发送另一个项目无法识别的数据类型。你甚至不需要更改任何功能,只需要更改发送的内容。或者,您可以从接收数据的程序中引用test1。

        4
  •  0
  •   Lex Li    14 年前

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

    如果坚持,请将此对象移动到其自己的程序集,并将其添加到两侧作为参考。这样,.NET Framework应该能够反序列化对象。