二进制消息序列化/反序列化的结构体

5
我刚接触C#二进制并有一个问题想请教,我正在尝试通信的应用程序具有特定的二进制消息格式。它必须以B8十六进制代码开始,并以BB十六进制代码结束,中间是二进制消息。那么,最好的方法是将字节缓冲区转换为易于访问消息属性的消息,我想到应该使用结构体,但老实说我不太确定。
编辑:
我之所以不想用二进制是因为我希望能在我的应用程序中轻松使用数据。例如,我想将代表命令类型的二进制位转换为枚举类型,像这样(只是我想做的事情的一种表示):
struct CommandMessage
{
    public CommandType Command { get; set; }
    public object Data { get; set; }
}

enum CommandType
{
    UserJoined,
    MessageReceived
}

1
这非常不清楚。你能发一个你试图做的例子吗?你为什么需要这个二进制消息?你用它做什么?为什么你想要一个不是 byte[] 的 C# 表示? - Oded
为了回答这个问题,我们需要准确地了解消息在byte[]中的布局 - 即它是否可以被逻辑上拆分为结构体(我真的不建议这样做)。特别是,任何“字符串”内容都意味着“否”。您还需要了解任何数据的字节顺序等。另外:在二进制中,“BB” / “B8”并没有什么神奇之处 - 如果float / int / string / guid /等内部自然发生“BB”或“B8”,您打算怎么办? - Marc Gravell
这个例子并没有解释“特定的二进制消息格式”,也没有解释你对BB/B8问题的处理。这个“特定的二进制消息格式”已经定义好了吗?还是你可以自由选择自己的布局? - Marc Gravell
请参考此链接:https://dev59.com/OHA75IYBdhLWcg3weY5f - DasKrümelmonster
1
K已经被定义了,但是您没有告诉我们它的定义是什么。因此,我们怎么能说您是否可以将其直接映射到一个结构体,或者建议最佳的前进路线呢?细节真的很重要。 - Marc Gravell
抱歉。B8在命令类型之前,而BB在命令之后并在数据之前。然后一个B8结束了消息。 - LordZardeck
1个回答

1

我建议使用protobuf-net来进行DTO序列化。

因此,定义一些实体,例如Package(在您的示例中为CommandMessage),该实体具有

public Command Command;

public byte[] Data;(使用protobuf序列化)

基于Command,您可以使用protobufData反序列化为具体的DTO类型。

如果您的消息应以特殊前缀开头,则也可以在Package中处理此问题。 此外,Package应该处理自己写入/从二进制流或缓冲区读取(这非常简单)。

例如:package.WriteTo(buffer)生成[BB,Command,Data,B8]。对于package.ReadFrom()也是一样。


据我从评论中了解到,@MarcGravell,这应该是可行的。让我解释一下:DTO使用protobuf进行序列化,但Package(DTO+Command的包装器)处理所有读/写逻辑。因此,假设我们有package.WriteTo(...),它会写入[BB,Command,Data(序列化的DTO),B8]。读取也采用同样的方法。 - illegal-immigrant
直到您在有效载荷中获得自然出现的B8。 - Marc Gravell

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