后端发送多个protobuffer消息到前端,前端用socket监听,如何区分消息类型呢?

 //定义心跳包

  DseHeartbeat _DseHeartbeat;
  DseHeartbeat _DseHeartbeat1;

 _DseHeartbeat.set_time(  );
char a[];
memset ( a ,,);
std::string str;
_DseHeartbeat.SerializeToString( &str );
memcpy(a,str.c_str(),str.length());
_DseHeartbeat1.ParseFromString(str);

定义了一个proto,设置int字段为当前的时间戳,可以看到被反序列化成了以上内容。

可以在string的前面添加两个字段,1个是4位的消息长度,另一个是4位的消息类型。

 enum S2C_EVENT
{
C2S_DceLimitTank = , //DceLimitTank
S2C_DseUserData = , //DseUserData
S2C_DseLimitTank = ,
S2C_DseActivityData = ,
S2C_DseHeartbeat = ,
};

定义几个消息的类型。

客户端在解析的时候:

int iostring_readInt ( const char* d ,int offset ) {
int ret = ;
d += offset;
ret = (*d & 0xff) << ; d++;
ret += (*d & 0xff) << ; d++;
ret += (*d & 0xff) << ; d++;
ret += *d & 0xff;
return ret;
}
void handleData ( int size ) {
int index = ;
while (index<size) {
int headlen = sizeof ( unsigned short )+ sizeof ( unsigned int );
int len = iostring_readInt ( buf+ index );
int pkgType = iostring_readInt ( buf + index ,sizeof ( unsigned int ) );
int requireLen = len - sizeof ( unsigned int );
if (requireLen> )
{
char* response = new char[requireLen];
memcpy ( response ,buf+index + ,requireLen ); std::string str2;
str2.assign ( response ,requireLen );
switch (pkgType) {
case S2C_DseHeartbeat:
qDebug () << _DseHeartbeat.ParseFromString ( str2 );
qDebug ( ("心跳包" + std::to_string ( _DseHeartbeat.time () )).c_str () );
break;
case S2C_DseActivityData: qDebug () << _DseActivityData.ParseFromString ( str2 );
qDebug ( ("活动:oil " + std::to_string ( _DseActivityData.oiltime () )).c_str () );
break;
case S2C_DseUserData: qDebug () << _DseUserData.ParseFromString ( str2 );
qDebug ( ("玩家名" + _DseUserData.name () +" level:" +std::to_string ( _DseUserData.level () )).c_str () );
break;
case S2C_DseLimitTank: _DseLimitTank.ParseFromString ( str2 );
_DropList = _DseLimitTank.maindrop ();
for (const DropData& _DropData1 : _DropList.droplist ()) {
qDebug () << (("droplist: type:" + std::to_string ( _DropData1.type () ) + " id:" + std::to_string ( _DropData1.id () ))).c_str ();
}
qDebug () << QString ( "错误码 %1" ).arg ( _DseLimitTank.res () ); default:
break;
}
}
index = index+len+;
}
}

因为客户端在recv的时候,可能一次读取多条消息,所以每次读取前四位(该消息的长度)->下四位(消息类型)->消息的内容->把消息ParseFromString 反序列化。

在这里反序列化失败过几次,因为protobuf里面还有'\0',所以,如果把char*直接赋值给string,\0会被丢弃。所以上面代码中memcpy ,assign都会保留\0。反序列化成功。

C++ protobuffer 前后端通信 简单应用的更多相关文章

  1. web——前后端通信原理

    前端向后台传输数据: 传输方法:post  get 区别: (1)get:用于从服务器获取数据,将参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看 ...

  2. web——前后端通信

    前端向后台传输数据: 传输方法:post  get 区别: (1)get:用于从服务器获取数据,将参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看 ...

  3. H5页面前后端通信 (3种方式简单介绍)

    1.ajax:短连接 2.websocket :长连接,双向的.   node搭建的websocket服务器,推送信息给客户端浏览器 :https://www.cnblogs.com/fps2tao/ ...

  4. express实现前后端通信上传图片,存储数据库(mysql)傻瓜教程(三)完结篇

    终于完成了所有自己想要的功能(鼓励下自己),虽然还是很简陋,但是还是挺有满足感的,哈哈. 附上前两篇的链接: 第一篇 第二篇 进入正题,在第二篇里面已经完成了连接数据库,并且实现了对数据库的增删改查, ...

  5. WebSocket 实现前后端通信的笔记

    之前在做站内信时,用到了 WebSocket ,整理了一些笔记分享如下.本文基于 SpringBoot 2.1.5,本文不涉及环境搭建. 引入依赖 在 Spring 中要使用 WebSocket 功能 ...

  6. 前后端通信中使用Ajax与后台接口api交互(以登录功能为例)

    一.查阅开发文档 首先,要做这个功能前,我们必须先查阅后台接口文档,了解使用登录接口时,需要提交哪些参数,并且接口使用返回的数据. 这里我使用了一个返回json格式数据的登录接口为例,讲解怎么使用Aj ...

  7. python 前后端分离 简单的数据库返回接口

    1.使用node http-server 起本地服务器  或者打开nginx 直接用nginx的默认页面也可以 (用下面的html文件替换nginx下html文件夹下的index.html) http ...

  8. 3-4章 第3章 form表单组件与小程序前后端通信

    View它相当于是一个点击触发一个事件,但是它的事件应该是相对来说可能是比较是偏向于页面上的一些展示,或者说是页面上的一些导航的一些跳转.Button它是一个标签, button是一个标签,一般去触发 ...

  9. 前后端通信—webSocket(支持跨域)

    WebSocket 的介绍 WebSocket 是什么 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 TCP ...

随机推荐

  1. 给 Windows 的终端配置代理

    初衷 由于项目开发使用go,所以经常要用到go get,但是吧,terminal下根本没办法下载啊,经常下载三个小时包,写代码一个小时 迫于无奈,只好找个方式可以在terminal下使用ss cmd下 ...

  2. 【linux杂记】Ubuntu查看端口使用情况

    转载地址: https://www.linuxidc.com/Linux/2016-01/127345.htm Ubuntu查看端口使用情况,使用netstat命令: 查看已经连接的服务端口(ESTA ...

  3. CLR 垃圾回收算法

    c#相较于c,c++而言,在内存管理上为程序员提供了极大的方便,解放了程序员与内存地址打交道,提高了程序员的工作效率.比如c中分配的malloc堆空间没有释放导致的内存泄露,数组越界导致的踩内存错误, ...

  4. 利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法

    1.利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法 首先判断字符串的长度是否为0,如果是,直接返回字符串 第二,循环判断字符串的首部是否有空格,如 ...

  5. 使用 cxf的程序 在win10 测试部署时报空指针异常

    2018-11-08 15:50:55.072 DEBUG 21524 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter  : ...

  6. ZOJ 3962:Seven Segment Display(思维)

    https://vjudge.net/problem/ZOJ-3962 题意:有16种灯,每种灯的花费是灯管数目,代表0~F(十六进制),现在从x开始跳n-1秒,每一秒需要的花费是表示当前的数的花费之 ...

  7. HDU 5773:The All-purpose Zero(贪心+LIS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5773 The All-purpose Zero Problem Description   ?? gets an ...

  8. kuangbin专题 专题一 简单搜索 迷宫问题 POJ - 3984

    题目链接:https://vjudge.net/problem/POJ-3984 这个题目,emm,上代码,看的估计应该是刚开始接触搜索的,我带点注释,你能慢慢理解. #include <ios ...

  9. 学Redis这篇就够了

    Redis 简介 Redis 优势 Redis 数据类型 string hash list set Zset 小总结 基本命令 发布订阅 简介 实例 发布订阅常用命令 事务 实例 Redis 事务命令 ...

  10. 【深入浅出-JVM】(5):Java 虚拟机结构

    Java 虚拟机基本结构 Java 堆 新生代.老年代划分 栈帧 感谢您的耐心阅读,如果您发现文章中有一些没表述清楚的,或者是不对的地方,请给我留言,您的鼓励是作者写作最大的动力. 作 者 : @mo ...