【发布时间】:2020-10-15 06:42:33
【问题描述】:
我正在使用 C# 创建一个客户端/服务器应用程序,我想知道在 C# 代码中处理数据包的最佳方法。
根据我的阅读,我可以 A)使用 Marshal 类从数据包原始缓冲区构造一个安全类,或者 B)在不安全的上下文中使用原始指针将数据包缓冲区直接转换为结构并使用它我的代码。
我可以看到这两种方法都有很大的问题。例如,使用 Marshal 似乎非常麻烦且难以维护(与指针解决方案相比),另一方面,在 C# 中指针的使用非常有限(例如,我什至不能声明非原始类型的固定大小数组这是此类应用程序中的交易破坏者)。
也就是说,我想知道这两种方法中哪一种更适合处理网络数据包,以及是否有其他更好的方法。我愿意接受任何其他可能的解决方案。
PS.:我实际上是在为已经存在的客户端/服务器应用程序创建一个自定义客户端,因此客户端和服务器之间的通信协议已经创建并且无法修改。所以我的 C# 客户端需要遵守这个已经存在的协议到其较低级别的细节(例如,数据包中每个信息的二进制偏移量是固定的,需要得到尊重)。
【问题讨论】:
-
坦率地说,您不应该通过编组器解码套接字数据。您应该编写一个协议处理程序,该处理程序相当手动地查看字节流,获取协议需要的内容。协议很少符合编组要求,甚至在讨论字节序、编码等之前。顺便说一句,c# 完全支持非基元的固定大小的缓冲区——它们被称为“固定缓冲区”
-
我有一个由 4 部分组成的博客系列,讨论了可能有用的现代方法,开始于:blog.marcgravell.com/2018/07/pipe-dreams-part-1.html
-
您正在处理网络的 7 层中的两个。 1) 通过流(TCP 或 UDP)串行发送数据的传输层。这就是 Marc link 所描述的。 2) 应用层,您有一个要发送/接收的类对象。所以你真的在问将类转换为字节和字节转换为类的应用层。 c# 是一个托管库,不容易允许字节与类之间的转换。
-
Microsoft 设计了 c# 托管库来消除 Win XP 之前(win 95、win 98、win 2000、win ME、WinNt)Windows 中经常出现的蓝屏崩溃。当指针未正确配置时,通常会出现蓝屏错误。因此,当 Net 3.5(与 Win XP 相同)几乎不可能使用指针并在托管库中添加了大量检查以防止蓝屏异常。 Marshal 库有防止蓝屏的检查,而不安全模式没有检查。
-
c# 不是将对象转换为字节的最有效语言(需要发送/接收)。您可以使用二进制序列化进行强制转换。如果您需要更高效的代码,请使用 c++。
标签: c# client-server marshalling