您的位置:首页 > 编程语言 > C语言/C++

【c#界面和后台c++通信】跨平台数据通信的选择:Google ProtoBuf

2013-12-30 16:04 961 查看
       本项目的windows客户端界面使用的是C# Winform界面编程简单实现,主要实现的是登录和设置两个界面。由于该界面不是最后的需求,合作方可能有大的改动,只是简单地实现客户端 的功能。为了使得界面和后台运行程序的完全解耦和,选择gooleProtobuf的数据通信格式,用Socket封装设置请求,界面和后台进行通信。

      以下非原创,由本人进行摘录。

引用:http://blog.sina.com.cn/s/blog_668aae7801019mdf.html

1 ProtoBuf的原理

    Socket通信中,客户端与服务器之间传递的是字节流。而在现实的应用中我们需要传递有一定含义的结构,使得通信的双方都能够识别该结构。实现对象(Class和Struct)Socket传输的关键就在于Class或Struct的序列和反序列化。

 Protobuf是google制定的一种对象序列化格式,开源地址:ProtoBuf:http://code.google.com/p/protobuf/

googleProtobuf的官方开源实现由java。c++和Python。而在.net下的实现有protobuf-net.(官方站点:http://code.google.com/p/protobuf-net/)而protobuf-net在序列化方面有着出色的性能,效率是.net二进制序列化几倍,而序列化后所占的空间也少于.net二进制序列化;除了以上两个优势外Protobuf有着一个更大的优势就是和其他平台交互的兼容性,在现有大部分流行的语言平台中基本都有Protobuf的实现.因此采用protobuf进行对象序列化是个不错的选择.

windows序列化机制的benchMarks比较:
http://mono.servicestack.net/benchmarks/NorthwindDatabaseRowsSerialization.1000000-times.2010-02-06.html
2 protobuf在C#中用Sockets传输的封装

原文链接:http://lanxinyuchs.iteye.com/blog/1108221

                  http://www.cnblogs.com/wu-jian/archive/2011/02/22/1961104.html

3 协议头结构体的Sockets传输

(1)发送的时候先要把结构转换成字节数组 

using System.Runtime.InteropServices;
/// 将结构转换为字节数组
/// 结构对象
/// 字节数组
public byte[] StructToBytes(object obj)
{
//得到结构体的大小
int size = Marshal.SizeOf(obj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(obj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
(2)接收的时候需要把字节数组转换成结构 

/// byte数组转结构
/// byte数组
/// 结构类型
/// 转换后的结构
public object BytesToStruct(byte[] bytes, Type type)
{
//得到结构的大小
int size = Marshal.SizeOf(type);
Log(size.ToString(), 1);
//byte数组长度小于结构的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配结构大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将byte数组拷到分配好的内存空间
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回结构
return obj;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: