2011-12-19 44 views
1

我正在开发一个发送大量数据包的网络应用程序。目前,我的序列化方法只是一个黑客,它需要一个对象列表并将它们转换为由管道字符'|'分隔的字符串。并将其刷入网络流(或通过UDP发送出去)。C# - 通过网络序列化数据包

我要寻找一个在C#中的清洁解决方案,这同时最大限度地减少 包大小(所以没有巨大的XML序列化)。

我的经验BinaryFormatter is SLOW。我也在考虑通过将它们编码为base64字符串来压缩我的数据包,并在客户端对它们进行解码。我希望看到如何影响我的应用程序的性能。

此外,另一个快速的问题:

我的设置创建2个插槽(一个TCP and UDP)和客户端连接单独对这两个插座。数据是根据需要刷新的(TCP用于重要的东西,UDP用于不重要的东西)。这是我第一次同时使用TCP/UDP,并且想知道如果有更统一的方法,虽然看起来不是这样,但是

非常感谢您的支持。

回答

2

我会使用类似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)的一大优点是不是每个端点都需要同时升级。以前的版本可以添加和使用新的字段而不会出错。这个版本的独立性是非常强大的,但也可以咬你,如果你不为它规划;)

0

我个人使用过下面的系统: 有抽象包类,所有包都是从中派生的。数据包类定义了两种虚拟方法:

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

该手动序列化使创建小型数据包成为可能。 在发送到套接字之前,数据包的长度前缀为前缀,并带有唯一的数据包类型标识号。接收端可以使用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(); 
    } 
} 
+0

我之所以避免BinaryReader/Writer是因为BinaryFormatter的速度有多慢。任何关于这个VS BFormatter的速度的想法? – 2011-12-23 19:06:05

0

我正在开发的是发送大量数据包的网络应用

退房networkComms.net ,一个开源的网络通信库,可能会为你节省一些时间。它包含protobuf序列化,其中一个例子是here 408行。