gpt4 book ai didi

c# - 使用 ProtoBuff.Net 通过 Socket 接收多种类型的对象

转载 作者:行者123 更新时间:2023-12-03 11:59:59 25 4
gpt4 key购买 nike

我正在实现一个自定义协议(protocol),两个应用程序将使用该协议(protocol)相互发送各种命令(包括文件传输,即大型二进制数据 block )。经过深思熟虑,我认为 protobuff 是用于此任务的正确序列化程序。使用 protobuff-net 进行序列化似乎非常简单。我遇到的问题是试图弄清楚如何在接收端反序列化各种对象,特别是当数据来自网络/套接字时。很多时候,我什至可能都不知道我是否有整个数据包要反序列化,并且不断调用 TryDeserializeWithLengthPrefix 似乎不是正确的方法。我的担忧是:

  • 如何实现一个方案,不仅可以确定消息类型,还可以确定数据包大小。我不能只使用 sizeof(Message) 因为在二进制 block 的情况下,实际的二进制数据可能会有所不同。我是否应该添加一个 MessageLength 字段作为所有消息继承的 BaseMessage 的第一个成员。然后首先通过指定 BaseMessage 类型调用 TryDeserializeWithLengthPrefix,这将为我提供序列化消息的实际长度,然后我确保已读取所需的字节数。如果是,那么我用实际的 MessageType 调用 TryDeserializeWithLengthPrefix?还有其他方法吗?
  • 我看到了 TryDeserializeWithLengthPrefix 的一些示例,它需要某种需要传入的查找表。在我的例子中,消息的类型很容易超过 50 并且随着应用程序的成熟而增长。实现查找表并跟踪所有消息类型似乎是个坏主意。是否有替代选项允许代码自动反序列化来自套接字的各种对象类型?
  • 最佳答案

    1)您可以实现您的对象,以便它们自己定义它们的类型。只需为每个对象创建类。如果需要,您可以使用继承。

    [ProtoContract]
    public class TransportObject1
    {
    ...
    [ProtoMember(1)]
    public byte[] data ...
    }

    如果你想继承类,只需做一个普通的 C# 继承,然后在 中添加类似 [ProtoInclude(9, typeof(ChildClass))] 的内容。基地 类(class)。

    关于您的二进制数据,您可以自己将其分成 block (例如,从源流中读取时等)并创建一个传输对象(如上所示的类),其中包含数据的 byte[] 成员。然后在接收方,您可以像接收任何其他对象一样接收这些对象,对其进行处理并将其数据从属性写入输出流。
    注意:您无需担心构建“一个大数据包”的数据包,该数据包将被反序列化为您的传输对象(类)。 TCP 会为您处理这个问题。
    但是您需要关心对属性中的数据进行排序和处理(以何种顺序将其写入接收方的输出流)。因为当您“同时”发送多个数据包( block )时,可能会以不同的顺序接收整个对象。所以你肯定想要对象中的某种 block ID。

    2)
    在接收数据的某些时候,您需要指定接收的数据类型(哪个类代表对象)。
    因为从套接字你只是接收字节和 Protocol Buffer 对类型一无所知。
    您可以实现某种具有固定大小 header (保存类型)的消息,然后读取此 header 并确定对象的类型。
    使用上面提到的解决方案,您在反序列化时不需要任何额外的查找表。 Protobuf-net 为您处理。
    只需将 Protobuf-net 的 Deserialize(..) 方法与您期望的类型参数一起使用(通过消息头中设置的类型)。
    您需要它,因为 Protocol Buffer 不保存有关对象中类型的任何信息。该类型纯粹由您期望反序列化的类型定义。
    如果您想要某种自动类型映射,您将需要使用另一个协议(protocol)来序列化和反序列化有关对象类型的信息。

    关于c# - 使用 ProtoBuff.Net 通过 Socket 接收多种类型的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29791841/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com