【问题标题】:C# Sending size of object with serialized object over Async socket connectionC# 通过异步套接字连接发送具有序列化对象的对象大小
【发布时间】:2010-11-03 23:13:07
【问题描述】:

我想序列化一个对象并通过网络发送它。我已经在我的类和 BinaryFormatter 上使用 ISerializeable 属性设置它以将对象转换为字节。我可以发送对象并在接收端反序列化它。但是,为了确保在尝试重建对象之前拥有整个对象,我想将大小与流一起发送。我想将前几个字节设置为大小,检查接收到的数据何时至少是这个固定大小,然后我可以读取并获取对象的完整大小。然后,只需等到我收到的数据是对象的大小+固定大小的字节。如何在流中偏移我的数据,以便我可以发送一个 int 来将对象的大小存储为前几个字节,并将我的对象存储为剩余字节?

【问题讨论】:

  • 拜托。对于您之前的问题(现已删除),我们刚刚确定它不是(反)序列化,而是 I/O。
  • 我发送数据并关闭流。然后我逐字节地从流中读取。在流中的任何点,长度始终为一个字节。我需要能够发送长度以了解流的长度,并确保我只接收一个对象,而不是另一个对象的一部分。
  • 如果你的 I/O 是正确的,格式化程序会处理长度

标签: c# serialization memorystream asyncsocket binaryformatter


【解决方案1】:

正确答案是:

SocketPacket socketData = (SocketPacket)asyn.AsyncState;
socketData.currentSocket.EndReceive(asyn);
byte[] data = socketData.dataBuffer;   

不是从 SocketPacket 中读取的正确方法

【讨论】:

    【解决方案2】:
    MemoryStream resultStream = new MemoryStream();
    resultStream.Write(BitConverter.GetBytes(objectStream.Length));
    resultStream.Write(objectStream.ToArray());
    
    // send the resultStream
    

    【讨论】:

      【解决方案3】:

      您能否仅序列化为MemoryStream,然后在完成后添加MemoryStream 中的.Length,然后是数据(使用GetBuffer() 并从数组中复制.Length 字节)。在接收器处倒车;读取长度(通常为 4 个字节),然后将那么多数据打包到 MemoeryStream 中;倒带MemoryStream (Position=0) 并反序列化。当然,你需要同意字节顺序等。

      (看,我什至没有提到保护……哦,其他的东西)

      【讨论】:

        【解决方案4】:

        您到底想防止什么? TCP 已经内置了一致性和可靠性检查。

        【讨论】:

        • 我的想法也是...除非 OP 通过 UDP 发送,但如果可靠性很重要,您就不会这样做。
        • 我想确保在创建对象之前接收到所有数据。由于我正在逐字节读取数据,并且我不知道是否在没有设置大小的情况下接收了所有数据。
        • @Chris:在这种情况下,终止字符要容易得多。
        • @Austin @Chris - 对于终止字符,您需要随时解析数据,以确保该字符在上下文中无效,例如作为 BLOB 或 Guid 的一部分。如果意图只是在反序列化之前缓冲数据,则 IMO 首选长度前缀。
        • @Austin 你能给我举个例子吗?我有一个自定义对象,但不知道如何向流中添加终止字符。
        猜你喜欢
        • 1970-01-01
        • 2011-05-14
        • 2011-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-13
        • 2013-09-02
        相关资源
        最近更新 更多