【问题标题】:C# - Serializing Packets Over a NetworkC# - 通过网络序列化数据包
【发布时间】:2011-12-19 20:22:53
【问题描述】:

我正在开发一个发送大量数据包的网络应用程序。目前,我的序列化方法只是一种 hack,它获取对象列表并将它们转换为由管道字符“|”分隔的字符串并将其刷新到网络流中(或仅通过 UDP 将其发送出去)。

我正在 C# 中寻找一个更简洁的解决方案,同时最小化 数据包大小(因此没有巨大的 XML 序列化)。

我对@9​​87654321@ 的体验。我还在考虑通过将数据包编码为base64 字符串并在客户端对其进行解码来压缩我的数据包。我想了解一下这将如何影响我的应用程序的性能。

另外,还有一个小问题:

我的设置创建了 2 个套接字(一个 TCP and UDP),客户端分别连接到这两个套接字。根据需要(TCP 用于重要内容,UDP 用于不重要内容),数据会根据需要刷新。这是我第一次同时使用 TCP/UDP 并且想知道

如果有更统一的方法,虽然看起来没有。

一如既往地感谢您的大力支持。

【问题讨论】:

    标签: c# networking serialization tcp udp


    【解决方案1】:

    我会使用类似于Google's Protocol Buffers 的二进制协议。使用 John Skeet 的 protobuf-csharp-port 可以分别在 IMessage 和 IBuilder 上使用 WriteDelimitedTo 和 MergeDelimitedFrom 方法。这些将在消息前面加上字节数,以便它们可以在另一端使用。定义消息非常简单:

    message MyMessage {
        required int32 number = 1;
    }
    

    然后你用ProtoGen.exe 构建C# 类,然后就去镇上。 protobuffers(特别是 protobuf-csharp-port)的一大好处是并非每个端点都需要同时升级。以前的版本可以添加和使用新字段而不会出错。这种版本独立性可能非常强大,但如果您不打算这样做,也可能会咬你;)

    【讨论】:

      【解决方案2】:

      您可以考虑使用ProtoBuf 进行序列化

      【讨论】:

        【解决方案3】:

        我个人使用过以下系统: 有抽象的 Packet 类,所有的包都派生自。包类定义了两个虚方法:

        void SerializeToStream(BinaryWriter serializationStream)
        void BuildFromStream(BinaryReader serializationStream)
        

        这种手动序列化使得创建小型数据包成为可能。 在发送到套接字之前,数据包是长度前缀和唯一的数据包类型 ID 号前缀。然后接收端可以使用 Activator.CreateInstance 构建适当的数据包并调用 BuildFromStream 来重构数据包。

        示例数据包:

        class LocationUpdatePacket : Packet
        {
           public int X;
           public int Y;
           public int Z;
        
           public override void SerializeToStream(BinaryWriter serializationStream)
           {
                 serializationStream.Write(X);
                 serializationStream.Write(Y);
                 serializationStream.Write(Z);
           }
           public override void BuildFromStream(BinaryReader serializationStream)
           {
                 X = serializationStream.ReadInt32();
                 Y = serializationStream.ReadInt32();
                 Z = serializationStream.ReadInt32();
           }
        }
        

        【讨论】:

        • 我之所以避免 BinaryReader/Writer 是因为 BinaryFormatter 的速度有多慢。关于这个 VS BFormatter 的速度有什么想法吗?
        【解决方案4】:

        我正在开发一个发送大量数据包的网络应用程序

        查看networkComms.net,一个开源网络通信库,可能会为您节省不少时间。它包含用于序列化的 protobuf,例如 here,第 408 行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-29
          • 1970-01-01
          • 2011-06-10
          • 1970-01-01
          • 1970-01-01
          • 2019-03-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多