后端发送多个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. C语言类型转换

    int/float to string/array: C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明. itoa():将整型值转 ...

  2. Fabric1.4源码解析:客户端安装链码

          看了看客户端安装链码的部分,感觉还是比较简单的,所以在这里记录一下.       还是先给出安装链码所使用的命令好了,这里就使用官方的安装链码的一个例子: #-n 指定mycc是由用户定义 ...

  3. java虚拟机-GC-新生代的GC、老年代的GC

    名词解释: GC:垃圾收集器 Minor GC:新生代GC,指发生在新生代的垃圾收集动作,所有的Minor GC都会触发全世界的暂停(stop-the-world),停止应用程序的线程,不过这个过程非 ...

  4. Akka-CQRS(16)- gRPC用JWT进行权限管理

    前面谈过gRPC的SSL/TLS安全机制,发现设置过程比较复杂:比如证书签名:需要服务端.客户端两头都设置等.想想实际上用JWT会更加便捷,而且更安全和功能强大,因为除JWT的加密签名之外还可以把私密 ...

  5. Object.toString()打印“地址”的原理

    Object.toString()打印"地址"的原理 @(java) 首先,打印的绝不是地址 public native int hashCode(); public boolea ...

  6. BZOJ 2039人员雇佣

    这道题教会我们一个道理靠谁也不如靠自己. 当时学长已经讲了,然而一脸懵逼,好吧,上网搜题解,二脸懵逼,于是自己动手,丰衣足食.自己推! 首先就是建模了,这道题谁与谁之间建模已经十分明了,超级源点,超级 ...

  7. [HNOI2012]矿场搭建 题解

    [HNOI2012]矿场搭建 时间限制: 1 Sec  内存限制: 128 MB 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出 ...

  8. 0x31 prime distance(质数)

    题目描述: 给定两个整数L和U,你需要在闭区间[L,U]内找到距离最接近的两个相邻质数C1和C2(即C2-C1是最小的),如果存在相同距离的其他相邻质数对,则输出第一对. 同时,你还需要找到距离最远的 ...

  9. CAD2014学习笔记-图层图案图块

    基于 虎课网huke88.com CAD教程 对象特性 选择对象点击特性栏/或右键点击特性 颜色:color 图层 线型:线的类型,如点状线.虚线等,若不改变则默认新建的线为该类型 线型比例:不同类型 ...

  10. SpringBoot之SpringApplication Explain

    SpringApplication Explain The SpringApplication class provides a convenient way to bootstrap a Sprin ...