【问题标题】:Serialization/Deserialization strategy for byte stream of C structs in C#C#中C结构字节流的序列化/反序列化策略
【发布时间】:2020-10-05 18:56:55
【问题描述】:

我正在开发一个用 C# 编写的客户端应用程序,它应该与旧版应用程序(我们称之为服务器)进行通信。问题是服务器的 API 被表示为一堆普通的旧 C 结构。每个结构都有一个 4 字节的标头和紧随其后的数据。它只是一个字节流。

我了解这种特殊的二进制格式是独一无二的(由旧版服务器应用程序提供)。因此,无法使用任何 SerDes 库,例如 Protocol Buffers,它使用其编码二进制数据的方式。

  • 是否有任何用于二进制序列化的项目/库允许我指定消息类型(如 protobuff 那样)及其二进制格式?我见过的每个库都基于 JSON、XML 或专有二进制格式。
  • 假设我决定编写自己的 SerDes 库(在 C# 中)。这样做的最佳/推荐策略是什么?我想以专业的方式做到这一点,至少在我的生活中一次。谢谢!

PS:我们只讨论小端序。

这是服务器定义消息的方式:

struct Message1
{
    byte    Size;       // Header 1st byte
    byte    Type;       
    byte    ReqI;       
    byte    Zero;       //Header 4th byte.

    word    UDPPort;    // Actual data starts here.
    word    Flags;      

    byte    Sp0;        
    byte    Prefix;     
    word    Interval;   

    char    Admin[16];  
    char    IName[16];  
};

【问题讨论】:

  • 我不清楚 C# 应用程序将如何与旧版应用程序通信。如果遗留应用程序是非托管代码,您应该查看有关封送处理、互操作和平台调用的信息。如果旧版应用程序是托管代码,它应该更容易沟通。
  • 旧版应用程序是非托管代码(它是用纯 C 编写的)。客户端和服务器之间的通信是使用标准套接字连接完成的。
  • 嗯,这样就没有序列化的余地了。您必须从网络流中读取字节并根据文档进行解析。据我了解,序列化是一个两阶段的过程。数据在一端序列化,通过某种介质传输,在另一端反序列化以重建原始状态。
  • 提示:您可以在 C# 中创建具有完全模仿 C 代码的显式布局的结构(请参阅最后几个字段的“固定缓冲区”);然后你可以使用 spans 和 MemoeyMarshal.Cast,然后用 boom: byte[] in,输入数据

标签: c# serialization deserialization protocol-buffers marshalling


【解决方案1】:

听起来您已经通过套接字连接发送了固定大小的 c 结构,您需要将它们解释为方便的 C# 类。

最简单的方法可能是使用托管 C++ 编写的代码进行所有消息处理。在这种情况下,您将拥有一个可能带有一堆 pragma 的结构,我确信可以使该结构具有与通过套接字发送的结构相同的内存布局。然后,您还将定义一个类似的托管 c++ 类(例如,包含托管字符串而不是 char 数组)。您还将编写代码,将结构字段逐个字段转换为这些托管类之一。将整个内容封装在一个 DLL 中,并将其作为依赖项包含在您的 C# 项目中。

这样做的原因是托管 C++,虽然它作为一种语言很奇怪,但它是非托管和托管代码和数据结构之间更容易的桥梁。无需编组任何东西,这是为您完成的。我使用他的方法创建了调用 Windows 硬件发现工具的库,没有(或没有)任何预先存在的 C# 库。使用托管 C++ 代码调用必要的 win32 函数比使用 C# 做同样的事情要容易得多。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2013-01-01
    相关资源
    最近更新 更多