protobuf前后端解析_protobuf 数据解析的2种方法

1 #include

2 #include

3 #include

4 #include

5

6 #include "person.pb.h"

7 #include "test.pb.h"

8

9 using namespacestd;10

11 classProtoMsgHandle12 {13 public:14 /*注册消息处理函数*/

15 voidinitHandles()16 {17 registerHandle(&ProtoMsgHandle::handleProtoPerson);18 registerHandle(&ProtoMsgHandle::handleProtoTest);19 }20

21 /*处理网络消息22 * data 为一个完整的数据包23 */

24 void handle(const char*data)25 {26 bool ret = false;27

28 const char * current=data;29

30 //在网络上传输的一个数据包总长度

31 int packetLength=0;32

33 //从第一个位置上获取到数据包总长度

34 memcpy(&packetLength, data, sizeof(int32_t));35

36 //指针后移

37 current+=sizeof(int32_t);38

39 //Message名字的长度

40 int protoNameLength=0;41

42 //从第二个位置上获取Message的名字的长度

43 memcpy(&protoNameLength, current, sizeof(int32_t));44

45 //指针后移

46 current+=sizeof(int32_t);47

48 //从第三个位置上获取Message的名字

49 stringname(current,protoNameLength);50

51 //指针后移

52 current+=protoNameLength;53

54 //取得Message的字节数

55 int messageSize=packetLength-(sizeof(int32_t)+sizeof(int32_t)+protoNameLength);56

57 do{58

59 msg_handle callback =m_callbacks[name];60

61 assert(callback !=NULL);62

63 if(callback ==NULL)64 {65 std::cout<GetPrototype(descriptor);76 assert(prototype !=NULL);77 if(prototype ==NULL)78 {79 std::cout<New();83 ret = msg->ParseFromArray(current,messageSize);84 if(ret)85 {86 (this->*callback)(msg);87 }88 else

89 {90 std::cout<

93 }while(0);94 }95 private:96 void handleProtoTest(test*test)97 {98 cout <price()="<< test->price() <userid()="<userid() <time()="<time() <age()="<age() <userid()="<userid() <name()="<name() <

109 private:110

111 typedef void (ProtoMsgHandle::*msg_handle)(::google::protobuf::Message*);112

113 mapm_callbacks;114

115 mapm_descriptors;116

117 template void registerHandle(void (ProtoMsgHandle::*callback)(MSGTYPE*))118 {119 const ::google::protobuf::Descriptor*des =MSGTYPE::descriptor();120 assert(des !=NULL);121 if(des !=NULL)122 {123 m_callbacks[des->full_name()] =(msg_handle)callback;124 m_descriptors[des->full_name()] =des;125 }126 }127

128

129 };130

131 classProtoMessageSender132 {133 public:134 /*发送proto msg到指定缓冲区135 * int32_t packetLength 数据包总长度136 * int32_t messageNameLength 消息名长度137 * char[] messageName 消息名138 * char[] Message 消息139 * char* buffer 缓冲区140 * int maxLength 消息的最大长度141 */

142 template static int sendMessageToBuffer(MSGTYPE& msg, char* buffer, intmaxLength){143

144 char * current=buffer;145

146 //Message的字节数

147 int messageSize=msg.ByteSize();148

149 //Message的名字

150 string messageName=MSGTYPE::descriptor()->full_name();151

152 //Message名字的长度

153 size_t messageNameLength=messageName.size();154

155 //消息组成 messageSize+messageNameLength+messageName+Message

156 size_t packetLength=sizeof(int32_t)+sizeof(int32_t)+messageNameLength+messageSize;157

158 if (packetLength>maxLength) {159 return -1;160 }161

162 //将数据包总长度放在第一个位置

163 memcpy(current, &packetLength, sizeof(int32_t));164

165 //指针后移

166 current+=sizeof(int32_t);167

168 //将Message名称长度放在第二个位置

169 memcpy(current, &messageNameLength, sizeof(int32_t));170

171 //指针后移

172 current+=sizeof(int32_t);173

174 //将协议名称放在第三个位置上

175 strcpy(current,messageName.c_str());176

177 //指针后移

178 current+=messageNameLength;179

180 //将Message放在第四个位置上

181 msg.SerializeToArray(current,messageSize);182

183 return (int)packetLength;184

185 }186 };187

188 intmain()189 {190

191 ProtoMsgHandle msghandle;192 msghandle.initHandles();193

194 test t;195 t.set_price(100.0);196 t.set_userid(110);197 t.set_time(123);198

199 person person;200 person.set_age(18);201 person.set_userid(200508);202 person.set_name("irons");203

204 char tmp[10*1024];205 ProtoMessageSender::sendMessageToBuffer(t, tmp, sizeof(tmp));206 msghandle.handle(tmp);207

208 ProtoMessageSender::sendMessageToBuffer(person, tmp, sizeof(tmp));209 msghandle.handle(tmp);210

211 cin.get();212 return 0;213 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值