找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5543|回复: 1

bstruct结构化二进制通信协议(V1.32 2013.07.30)+google下载

[复制链接]
发表于 2012-12-13 11:12:31 | 显示全部楼层 |阅读模式
本帖最后由 serverdev2012 于 2013-7-30 17:55 编辑

        前段时间一直说要写一个分布式的内存nosql,本周开始准备动手写业务了,发现通信消息的构造与解析是个不小的工作量,所谓工欲善其事,必先利其器,于是写了这个通信协议,为什么不直接用protobuf,有2点主要原因
1.依赖第三方库,给用户安装部署上造成不方便
2.protobuf对每一个报文要定义个报文说明文件,然后生成一个类,也就是说,系统中将充斥着大量的报文类,这不是我希望看到的,虽然OOP就是如此,但我不希望如此极端。

我希望就一个类,解决所有报文,于是写了这个二进制的数据结构通信协议,该协议同样具备xml的结构化特性,基本可以看作一个二进制的xml,本着共建共享的精神,于是也在github上开源出来,一方面希望为大家带来便利,同时希望有空的朋友一起来完成java php python等语言的版本

协议介绍
二进制结构通信协议将结构以二进制方式保存到byte流中当前支持语言:C++,希望有空的朋友一起来完成java php python等语言的版本,想参与的朋友联系我QQ:49038554
在C++中对应的类为BStruct

协议格式:流长度(1.21版开始没有此数据)+ 成员1+...+成员n(成员之间没有分隔符)

成员也是一个二进制流格式:成员名长度(unsigned short字节序同上)+成员名(字符串不包含没有\0)+值长度(unsignedshort)+(可以是一个嵌套的BStruct或BArray)

数组编码格式:元素大小(unsigned short,0表示元素大小变长)+元素1+...+元素n
元素编码格式:
      如果元素大小非0(定长元素),就是一个值
      如果元素大小为0(变长元素),值长度(unsigned short) + 值   

(1.30版本开始已经突破此限制)一个BStruct最大拥有256个成员,不够用时,可嵌套BStruct扩展
        
成员名长度限制:1~256byte



        数据类型:
            short int long int32 int64等各整型数的字节顺序:高位在前,底位在后
            不建议跨语言使用float double struct(c/c++专用),因为保存方式为memcpy方式复制进byte流,字节序为机器/系统api默认,其它语言不一定可以正确解析



协议样例(绿色为说明)
2D00 结构长度 :45byte msgid(11)+Student(34) 1.21版开始没有此数据
    0500 msgid      成员名:成员名长度5byte,成员名: msgid
        0200 D107   msgid值:值长度2byte,值2001
    0700 Student    成员名:成员名长度7byte,成员名:Student
        1700 值长度:23byte,值:一个BStruct(2结构长度 +21结构内容 )
            Student的值是一个嵌套的BStruct结构
            1500 结构长度:21byte name(13)+aga(8) 1.21版开始没有此数据
                0400 name        成员名:成员名长度4byte,成员名:name
                    0500 huoyu   name值:值长度5,值huoyu
                0300 age          成员名:成员名长度3byte,成员名:age
                    0100 1F        age值:值长度1,值31岁

使用范例:
BStruct结构转换进buf

    char buf[256];
     bsp::BStruct msg;
     msg.Bind(buf,256);//绑定buf,添加数据都会复制入buf末尾
     msg["msgid"] = (unsigned short)2001;//添加成员消息id,unsigned short类型
     bsp::BStruct Student;//创建成员学生
    /*
         将Student与msg的缓冲末尾绑定(连接)
         写入Student的数据,会直接写入msg末尾(即buf末尾)
      */

     Student.Bind(msg.PreBuffer("Student"), msg.PreSize() );
     Student["name"] = "huoyu";
     Student["age"] = (char)31;
     msg["Student"] = Student;//添加成员Student
     msg.GetStream();//得到buf地址
     msg.GetSize();//得到数据长度


从buf转回BStruct结构
     char buf[256];//BStruct流
     short size;//数据长度
     //解析BStruct
     bsp::BStruct msg;
     if ( !msg.Resolve(buf,size) ) return;//解析
     if ( !msg["msgid"].IsValid() ) return;//检查msgid是否存在,因为是范例,以下数据不再检查
     unsigned short msgid = msg["msgid"];//取得msgid
     bsp::BStruct Student = msg["Student"];//取得Student
     string name = Student["name"];//取得name
     char age = Student["age"];//取得age

相关连接
github下项目地址:https://github.com/huoyu820125/bstruct
googlecode下载地址:http://code.google.com/p/bstruct/

目前版本 V1.23

更新历史
V1.32(2013.07.30)
支持android的ndk


V1.31(2013.01.16)
1.对Null字符串,0长度字段增加支持2.增加IsEmpty接口用于判断,字段存在,但是值为NULL

V1.30(2012.12.19)
增加BArray,二进制数组编码
对数组进行支持
BStruct可与BArray互相嵌套

BStruct成员个数突破256限制(前一个无版本号的版本中更新的内容)



V1.23(2012.12.18)
更新时候忘记了前一版本是1.21,直接将版本号跳到了1.23
扩大BStruct兼容的大小,从unsigned short扩大大unsigned int
相应的修正相关方法与成员类型


V1.21(2012.12.18)
将编码头部的2byte总长度从编码中删除,向json xml一样,不带头部信息
由用户在不同场合自己定义头部

相应的解码时,获取BStruct大小的方式就不再是short len = memtoi( buf, 2 )了,
按照用户自己定义的头部解析了。

V1.20(2012.12.14)
主要加强了对非法数据流的适应能力
1.删除所有assert
2.可以得到赋值/取值成功/失败结果
   取值检查:msg[""].IsVaild()
   赋值检查:if ( !(msg[""] = 值) )
3.BStruct增加IsVaild()方法检查一个BStruct对象是否有效,主要用于解析嵌套的BStruct
msg["key"].IsVaild()可能是有效的数据,但msg["key"]如果不是一个BStruct,那么BStruct sub = msg["key"];sub可能就是无效的(无法解析msg["key"]指向的二进制流)



V1.0(2012.12.12)
发布,支持C++语言





发表于 2012-12-21 09:57:37 | 显示全部楼层
谢谢楼主,下载来看看学习,
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-4 01:19 , Processed in 0.017652 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表