Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >protobuf 序列化到文件及反序列化

protobuf 序列化到文件及反序列化

作者头像
changan
发布于 2020-11-04 07:03:43
发布于 2020-11-04 07:03:43
1.9K00
代码可运行
举报
运行总次数:0
代码可运行

项目应用

游戏中,将对局的数据保留下来,用于对局回顾及debug等用途,由于协议采用PB,故以二进制的pb格式写入文件,在使用该对局内容的时候,按照格式反序列化出来用于播放对局、压测数据构造等。

涉及的部分: pvp服务器,产生对局数据,然后通过路由发送到recordsvr,一个专门写文件的服务器,写完文件后,使用时对文件解析。

文件的格式: head-data-head-data….

相关的协议如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
message RecordReq
{
    optional uint64 game_id = 1;
    optional string record_name = 2;
    optional bool finish = 3;
    optional RecordPkg Pkg = 4;
}

message RecordPkg
{
    optional uint32 time_offfect = 1;
    optional uint32 cmd = 2;
    optional bytes fragment_data = 3;
}

message RecordHead
{
    required fixed32 cmd = 1;  
    required fixed32 len = 2;
    required fixed32 time_offect = 3;
}

pvp对局服务器,产生数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void CPvPGame::SendRecord(uint16_t uiCmd, const Message* msg, bool bFinish/* = false*/)
{
    unsigned int uiNow = CSingletonPvPDateTime::instance()->GetSec();
    uint32_t uiTimeOffset = uiNow - m_battleInfo.battle_base.battle_start_time;

    RecordReq msgReq;
    RecordPkg* pPkg = msgReq.mutable_pkg();
    if (NULL == pPkg)
    {
        return;
    }
    msgReq.set_game_id(GetGameId());
    msgReq.set_record_name(GetRecordName());
    msgReq.set_finish(bFinish);
    pPkg->set_time_offfect(uiTimeOffset);
    pPkg->set_cmd(uiCmd);


    if (GAME_RECORD_START == uiCmd || GAME_RECORD_END == uiCmd)
    {
        GameDataInfo gameData;
        FillGameInfo(&gameData);
        //修正starttime
        gameData.mutable_game_init_info()->set_start_time(m_uiStartTime);
        gameData.SerializeToString(pPkg->mutable_fragment_data());
    }
    else if (NULL != msg)
    {
        msg->SerializeToString(pPkg->mutable_fragment_data());
    }
    else
    {
        return;
    }

    int iRet = 0;
    iRet = CSingletonPvPProcessor::instance()->
        SendMsgToAllServerByIdc(GetOwer(), RecordSvrCmd::RECORD_REQ, msgReq, SERVER_FAMILY_RECORDSVR);

录像服务器,专门写文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::stringstream sstrNameTmp;
sstrNameTmp << szRecordDir << "/tmp_" << msgReq.game_id() << "_tmp";

RecordHead rHead;
rHead.set_cmd(msgReq.pkg().cmd());
rHead.set_len(msgReq.pkg().fragment_data().size());
rHead.set_time_offect(msgReq.pkg().time_offfect());

//std::fstream output(sstrNameTmp.str().c_str(), std::ios::out | std::ios::binary | std::ios::app);
std::fstream& output = OpenFile(sstrNameTmp.str().c_str());

std::string strout;
rHead.SerializeToString(&strout);
output << strout;
if (msgReq.pkg().has_fragment_data())
{
    output << msgReq.pkg().fragment_data();
}

//output.close();

LOG_DEBUG(0, 0, "write record|%lu|%s", msgReq.game_id(), sstrNameTmp.str().c_str());
LOG_DEBUG(0, 0, "write record|%lu|%d|%s", msgReq.game_id(), rHead.ByteSize(), rHead.ShortDebugString().c_str());

if (msgReq.finish())
{
    CloseFile(sstrNameTmp.str().c_str());
    rename(sstrNameTmp.str().c_str(), strLogName.c_str());
    LOG_DEBUG(0, 0, "rename|%lu|%s|%s", msgReq.game_id(), sstrNameTmp.str().c_str(), strLogName.c_str());
}

解析对局数据,用于回放或性能测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  bool Robot::ReadData()
  {
m_IsInitGameDataInfo = true;
      char* writebuff=RunTime::GetInst()->getwritebuff();
      long filelength=RunTime::GetInst()->getfilelength();
      DEBUG("enter ReadData");
      DEBUG("writebuff len:%d,length:%ld",(int)strlen(writebuff),filelength);

/*
message RecordHead
{
	required fixed32 cmd = 1;  //cmd 为0的时候,包体为GameDataInfo结构
	required fixed32 len = 2;
	required fixed32 time_offect = 3;
}
*/
// 先 算一个包头
RecordHead recHead;
recHead.set_cmd(869);			// GAME_RECORD_START
recHead.set_len(1024);			//  fixed32  any 32 bit
recHead.set_time_offect(1024);	// fixed32; any 32 bit
std::string strout;
recHead.SerializeToString(&strout);
int HeadSize = strout.size();

recHead.ParseFromArray(writebuff, HeadSize );
DEBUG("RecordHead: %s", recHead.ShortDebugString().c_str());

m_gameDataInfo.ParseFromArray(writebuff + HeadSize, recHead.len());
DEBUG("m_gameDataInfo: %s", m_gameDataInfo.ShortDebugString().c_str());
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Impala Plan Schedule
数据库中一个逻辑查询计划生成后, 需要进行ToPhysical Plan 转化为物理的查询计划, 本文主要讲解 Scan算子 是怎么初始化和分发的, 其他算子可类推
jasong
2024/09/23
1670
【protobuf源码探秘】编码、序列化
早就想写了,不过前面有redis源码学习的系列在,就一直拖着。 在我学protobuf的时候,在网上看到一个博客,说的挺好,但是偏偏插了这么一句:fixed 和 int 相比,fixed重时间、int重空间。所以如果对空间性能有要求的话就使用int… 吧啦吧啦的。
看、未来
2022/01/10
7900
【protobuf源码探秘】编码、序列化
Protobuf3语法详解
定义一个消息类型 先来看一个非常简单的例子。假设你想定义一个“搜索请求”的消息格式,每一个请求含有一个查询字符串、你感兴趣的查询结果所在的页数,以及每一页多少条查询结果。可以采用如下的方式来定义消息类型的.proto文件了: syntax = "proto3"; message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; } 文件的第一行指定了你正在使用proto3语法:
生活创客
2018/06/11
5.7K0
protobuf 的 C++函数使用手册
在生成的.h文件中定义了类成员的访问方法。例如,对于Person类,定义了name、id、email、phone等成员的访问方法。
看、未来
2021/12/20
2.4K0
ijst:基于反射的 C++ JSON 反序列化库
ijst (iJsonStruct) 一个是 C++ Json 序列化/反序列化库:
h46incon
2018/08/20
3.5K0
关于 protobuf 在网络传输中数据丢失问题解决方案
确定问题不是出在protobuf这边之后,那就只能是网络传输过程或者传输前后的字符串转化过程中出现问题了。
看、未来
2021/12/17
6180
Unity Metaverse(三)、Protobuf & Socket 实现多人在线
•根据语法规则编写.proto文件;•通过编译工具protoc.exe将.proto文件编译成.cs文件;
CoderZ
2022/08/29
1.2K0
Unity Metaverse(三)、Protobuf & Socket 实现多人在线
【ProtoBuf】文件编写及序列化
为了快速上手以及完整的使用ProtoBuf,我们将编写一个小项目,并根据PB学习程度对这个项目来逐渐改版,每一个版本对应PB的新知识点。在后续内容中,会使用简单的通讯录作为项目实现。
用户11029129
2025/02/18
1770
【ProtoBuf】文件编写及序列化
google protobuf学习笔记:编译安装、序列化、反序列化
简介 protobuf也叫protocol buffer是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 、json进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。 prot
_gongluck
2018/03/09
13.4K1
protobuf篇:介绍、安装、官方教程翻译、测试
综上所述目前最好的设计消息数据包方式是服务器和客户端通信协议推荐用protobuf,服务器存入数据库时用json。
看、未来
2021/10/28
1.7K0
protobuf篇:介绍、安装、官方教程翻译、测试
深入protobuf(Protocol Buffers)原理:简化你的数据序列化
Protocol buffers 是⼀种语⾔中⽴,平台⽆关,可扩展的序列化数据的格式,可⽤于通信协议,数据存储 等。Protocol buffers 在序列化数据具有灵活、⾼效的特点。
Lion 莱恩呀
2024/11/04
5K0
深入protobuf(Protocol Buffers)原理:简化你的数据序列化
网络基础『 序列化与反序列化』
本文将介绍如何使用C++实现简单的服务器和客户端通信,并重点讲解序列化与反序列化的概念和实现。这篇文章将深入探究数据在网络传输中的转换过程,以及如何在C++中应用这些技术
北 海
2024/05/25
2081
网络基础『 序列化与反序列化』
【protobuf】四、proto3语法详解③ -- 默认值 && 消息更新规则 && option选项
​ 反序列化消息时,如果被反序列化的二进制序列中不包含某个字段,反序列化对象中相应字段时,就会设置为该字段的默认值。不同的类型对应的默认值不同:
利刃大大
2025/02/08
2600
【protobuf】四、proto3语法详解③ -- 默认值 && 消息更新规则 && option选项
Protocol Buffers十分钟上手:入门示例
Protocol Buffers是Google出品并开源的语言和平台均中立的数据序列化和反序列化工具,官方支持C++/Java和Python三大语言,另外有大量的第三方实现支持PHP、D语言和C#等众多语言,这些都可以从Google Protocol Buffers的官方网站上找到链接。
一见
2018/08/07
6500
Protobuf协议?盘他!
Protobuf是Google基于C++ 进行的实现的一套数据序列化/反序列化库,开发人员可以根据 ProtoBuf 的语言规范生成多种编程语言(C++、Python、Java 等)的接口代码。使用ProtoBuf的文件在存储效率上和处理性能上都元高于XML,也具有更好的跨平台性,使用灵活。
audy
2019/04/28
1.5K0
Protobuf协议?盘他!
protobuf、flatbuffer、msgpack 针对小数据包的简单对比
前段时间我尝试给 atframework 的 libatapp 整合进UnrealEngine做Dedicated Server和逻辑server通信的时候碰到了一些问题。主要在于这些客户端引擎一般来说默认都是关闭exception的甚至会关闭RTTI。而 libatapp 所依赖的通信组件 libatbus 里内部协议是msgpack , 而 msgpack 的官方 C++ 的header only的实现是必须开异常的功能的。所以我近期打算抽空增强一波 libatbus 的功能,增加一些跨版本向前向后兼容功能,和一些简单的验证功能(仅仅是为了防止误操作导致的问题)。具体的变更等我弄完了再发一篇。
owent
2020/01/02
8.7K0
Protocol Buffers C++入门教程
protobuf(Protocol Buffers )是Google的开源项目,是Google的中立于语言、平台,可扩展的用于序列化结构化数据的解决方案。官网见:here,源码见:github。
恋喵大鲤鱼
2018/08/03
13.2K0
Protocol Buffers C++入门教程
CVE-2016-3510:Weblogic反序列化
CVE-2016-3510漏洞是对CVE-2015-4852漏洞修复的绕过,攻击者在可以通过该漏洞实现远程命令执行。
Al1ex
2021/07/21
2.1K0
CVE-2016-3510:Weblogic反序列化
Protobuf简单使用
如果 .proto 文件包含 package 声明,则该文件的所有内容都将放置在相应的 C++ 命名空间中。例如,给定 package 声明
Andromeda
2024/07/27
1550
强大的序列化工具:Protocol Buffers
Protocol Buffers 为结构化数据的序列化向前兼容,向后兼容,提供了语言中立、平台无关、可扩展机制的途径。类似JSON,但比JSON更小、更快。
Yuyy
2022/09/21
2.1K0
相关推荐
Impala Plan Schedule
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验