skynet sproto协议剖析(二)

这篇试着对着代码分析一下sproto协议.

一个典型的sproto协议长如下的样子:

.package {  
    type 0 : integer  
    session 1 : integer  
}

.Info  {
    money 0 : integer
    sex 1 : integer
}

TestReq 1 {
    request {
        addr 0: *string 
        info 1: Info
        age 2: *integer
        nClubID 3: integer
        name 4: string
    }
    response {
        addr 0: integer
    }
}

根据代码的定义,一个完整的协议结构体sproto主要包括sproto_type数组和protocol数组,以及他们各自的个数,定义如下:

	struct sproto {
		struct pool memory;
		int type_n;
		int protocol_n;
		struct sproto_type * type;
		struct protocol * proto;
	};

拿上面的协议文件举例,protocol只有一个TestReq,而sproto_type有四个,分别是:

package,Info,TestReq.request,TestReq.response. 注意看最后两个,他们是在TestReq协议中定义的.

结构体protocol的定义如下:

	struct protocol {
		const char *name;   //协议名字,如"TestReq"
		int tag;            //协议tag,上面是1
		int confirm;	// confirm == 1 where response nil
		struct sproto_type * p[2];     //对应TestReq.request和TestReq.response
	};

各字段的含义已经在注释里.

sproto_type的定义如下:

struct sproto_type {
		const char * name;    //名字,如"package"
		int n;                //field的个数,如Info有2个,TestReq.request有5个
		int base;
		int maxn;
		struct field *f;      //字段结构体
	};

field就是来定义要交换的数据结构的,定义如下:

	struct field {
		int tag;        //如addr为0
		int type;       //数据类型0为integer 2为数组 字符串 3为复合结构
		const char * name;  //如"addr"
		struct sproto_type * st;  //复合结构指向的sproto_type,内置类型为NULL
		int key;        //为map定义的key索引
		int extra;
	};

协议文件经打包后生成二进制数据,经解析之后对应一个sproto数据结构.一个简单的协议二进制数据如下:



可以看出数据主要分成了sproto_type和protocol两部分,图中的head,f1,f2字段和上篇中介绍的格式一致.

sproto_type或protocol数组的个数是由字段大小来计算得出的.

例如,spoto_type数组的总长度为0x93个字节.第一个元素的大小为0x47个字节,再往后读0x47个字节占用的大小为0x47+4小于0x93,故后面还有该类数据,继续读4字节为0x44,此时正好占用的数据为0x47+4+0x44+4=0x93,所以sproto_type数据读取完毕.

后面的protocol占0x17个字节,紧接着读取到第一个数据占0x13个字节,正好用完0x17个字节,所以protocol只有一个元素.

我们再来分析一下sproto_type数据的构成,如下图


后面0x2a个字节才是真正标识field数据的地方.例如各种不同的类型就是在type这个字段里表现的.

接下来分析protocol的结构:


好了,协议二进制文件格式就都讲到了,后面会讲如何实现打包解包.


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值