【游戏】服务器性能测试(五)网络协议包序列化

简介: 网络游戏前后端通信的消息协议始终是基于制定的规则,即发送端使用什么样的方式进行序列化,接收端就需要使用对应的方式进行反序列化,只有这样才能保证发收双方能够正常“交流” 消息协议的组成离不开基础数据类型,这些数据类型包括单字符(char)、短整型(short)、整型(int)、长整型(long long)、浮点数(float,double)、字符串(char* / string)。这些数据类型具体占多少字节可以参考游戏协议测试一:协议测试介绍。

【游戏】服务器性能测试(五)网络协议包序列化


目录


【游戏】服务器性能测试(一)阈值


【游戏】服务器性能测试(二)容灾


【游戏】服务器性能测试(三) 性能指标


【游戏】服务器性能测试(四) 简单压测工具理论篇


一、前言


   上一期介绍了压力测试工具的设计思路,接下来的几期会逐步拆分其中的模块进行单独说明,今天介绍的内容是关于通讯协议的序列化与反序列化,其实理解后也非常的简单易懂。


二、字段类型与序列化


   网络游戏前后端通信的消息协议始终是基于制定的规则,即发送端使用什么样的方式进行序列化,接收端就需要使用对应的方式进行反序列化,只有这样才能保证发收双方能够正常“交流”


   消息协议的组成离不开基础数据类型,这些数据类型包括单字符(char)短整型(short)整型(int)长整型(long long)浮点数(float,double)字符串(char* /  string)。这些数据类型具体占多少字节可以参考游戏协议测试一:协议测试介绍


   消息协议通常由长度+消息号+协议内容组成,那如何进行协议组装呢?首先消息协议可以看作是一连串的单字符组成的数据,我们只需要将其他数据类型的数据按相应进行转换成单字节字符数组,然后合并发送即可。


# c语言网络send方法的定义,char* 其实就是由char组成的数组
int send(SOCKET s,const char *buff,int len,int flag);


   那么这里主要以int(整型)为例进行介绍如何转换成char*格式。首先int是由4个字节组成。例如16909060可以表示为(1<<24) |(2<<16)|(3<<8)|4。可以使用移位的方式进行拆成4个单字节组成如下代码。


# c/c++
int v = 16909060;
char h1 = (v >> 24) & 0xFF; # 暂时忽略有无符合
char h2 = (v >> 16) & 0xFF;
char l1 = (v >> 8) & 0xFF;
char l2 = v & 0xFF;
print("h1=%d, h2=%d, l1=%d, l2=%d",h1, h2, l1, l2) # 1,2,3,4
# 这样就将int v转化成 char数组
char* v_to_chars = {h1, h2, l1, l2}


   通过上面的代码就可以将1个int的数转成char*的表示方法。那么针对short、long long原理也是如此,浮点数就需要特殊处理一下,然后字符串本身就是char*因此不需要做转化。


# c/c++
# 协议结构为 协议长度(int) + 协议消息(short) + 协议内容
short msgID = 0x2002;
char* data = "hello world!";
#计算 4 + 2 + data的长度
int len = sizeof(int) + sizeof(short) + strlen(data)
char* packet = new char(len);
# 以下是伪代码填充packet
packet[0~3] => {len>>24&0xFF, len>>16&0xFF,len>>8&0xFF,len&0xFF}
packet[4~5] => {msgID>>8&0xFF, msgID&0xFF}
packet[6~] => data
# 调用send方法即可发送序列化好的协议内容出去
send(socket, packet, len, 0);


   根据以上方法即可完成对协议的序列化发送,虽然本例代码中协议内容仅只有一个字符串,了解基本的方法后,添加其他复杂的内容无非是做更详细的转换后组装起来。注:本例做了一个错误的示范即字符串通常发送时前面会额外增加表示这个字符串长度的字段变成`packet_len + msgID + data_len + data`


   另外假设我把int v的表示char*表示方法由`{h1, h2, l1, l2}` 变为 `{l2, l1, h2, h1}`即倒转过来是不是也可以呢?答案是可以,这是一个新的概念:大小端,具体内容可以参考百度搜索。


   通过上面的介绍应该差不多对协议的序列化有一定的了解,但其实在日常的工作开发中,上面这一层面往往是封装好的,业务同学只需要调用类似下面的代码即可。


Packet packet;
packet.writeShort() # 写入短整型
packet.writeInt()  # 写入整型
packet.writeByte() # 写入单字节
packet.writeString() # 写入字符串
packet.writeFloat() # 写入浮点数
# 然后发送出去
some_obj.send(packet)

   

三、扩展内容


   1. 数组序列化


       数组是非常常见的数据存储方式,例如玩家的好友列表通常是一个数组,通常的序列化方式是数组元素总数+数组个元素数据写入


Friend myFriends[10];
packet.writeShort(10) # 数组长度
for(f : myFriends) # 遍历写入每个元素的数据
{
  packet.writeInt(f.id);
  packet.writeString(f.name); 
  packet.writeInt(f.level);
}


   2. 有符号和无符号


       针对char、short、int都会需要考虑数据的表示范围,就会接触到有符号或无符号。那么在C/C++中可以定义unsigned即可,而对应java就需要&0xFF进行转化。


   3. 不同语言的序列化库


      3.1. python语言可以使用自带的struct库,通过pack进行打包序列化,unpack进行反序列化。


#python 可以使用struct
struct.pack("i",111)
struct.pack("3s","aaa")


          3.2. java语言可以自己实现,也可以使用ByteBuffer类,序列化使用putXXX,反序列化使用getXXX即可。


# java nio.ByteBuffer
b = ByteBuffer.allocate(size)
b.putInt(111)
b.putShort(22)


四、协议的反序列化


   只要理解了协议的序列化后,反序列化即按照对应的方法反过来即可,具体如下代码演示。

 

char* data = "xxxx"
char h1 = data[0]
char h2 = data[1]
char l1 = data[2]
char l2 = data[3]
int v = (h1<<24&0xFF) | (h2<<16&0xFF) | (l1<<8&0xFF) | (l2&0xFF)


   关于协议的序列化和反序列化就介绍到这里,如有疑问可以关注我的微信公众号给我留言哦,希望对大家有所帮助!


欢迎微信搜索"游戏测试开发"关注一起沟通交流。

相关文章
|
6月前
|
SQL 分布式计算 Serverless
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
鹰角网络为应对游戏业务高频活动带来的数据潮汐、资源弹性及稳定性需求,采用阿里云 EMR Serverless Spark 替代原有架构。迁移后实现研发效率提升,支持业务快速发展、计算效率提升,增强SLA保障,稳定性提升,降低运维成本,并支撑全球化数据架构部署。
559 56
鹰角网络:EMR Serverless Spark 在《明日方舟》游戏业务的应用
|
3月前
|
JSON 监控 API
在线网络PING接口检测服务器连通状态免费API教程
接口盒子提供免费PING检测API,可测试域名或IP的连通性与响应速度,支持指定地域节点,适用于服务器运维和网络监控。
|
3月前
|
机器学习/深度学习 存储 监控
内部文件审计:企业文件服务器审计对网络安全提升有哪些帮助?
企业文件服务器审计是保障信息安全、确保合规的关键措施。DataSecurity Plus 是由卓豪ManageEngine推出的审计工具,提供全面的文件访问监控、实时异常告警、用户行为分析及合规报告生成功能,助力企业防范数据泄露风险,满足GDPR、等保等多项合规要求,为企业的稳健发展保驾护航。
|
4月前
|
存储 运维 API
HPE OneView 10.0 - HPE 服务器、存储和网络设备集中管理软件
HPE OneView 10.0 - HPE 服务器、存储和网络设备集中管理软件
83 1
|
2月前
|
存储 弹性计算 网络协议
阿里云服务器ECS实例规格族是什么?不同规格CPU型号、处理器主频及网络性能参数均不同
阿里云ECS实例规格族是指具有不同性能特点和适用场景的实例类型集合。不同规格族如计算型c9i、通用算力型u1、经济型e等,在CPU型号、主频、网络性能、云盘IOPS等方面存在差异。即使CPU和内存配置相同,性能参数和价格也各不相同,适用于不同业务需求。
|
2月前
|
存储 监控 Linux
Dell OpenManage Enterprise 4.5 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.5 - Dell 服务器、存储和网络设备集中管理软件
46 0
|
3月前
|
弹性计算 运维 Linux
3分钟幻兽帕鲁游戏链接服务器一键部署教程,基于阿里云服务器
本教程介绍如何使用阿里云服务器快速部署《幻兽帕鲁》联机服务,支持与好友联机游戏。内容包括服务器配置、计费说明、服务创建及登录游戏步骤,同时提供存档管理与配置修改方法,助您轻松搭建专属游戏服务器。
|
6月前
|
JavaScript 数据可视化 Docker
简易制作MCP服务器并测试
本文介绍了如何简易制作并测试MCP服务器,包括环境搭建、代码实现及Docker部署。首先通过uv包创建项目,在main.py中定义MCP服务器及其工具和资源函数。接着详细说明了在Windows上安装uv、配置Docker镜像加速、生成requirements.txt文件以及编写Dockerfile的过程。最后,通过构建和运行Docker容器部署MCP服务器,并使用Node.js工具测试其功能,确保服务器正常工作。此教程适合初学者快速上手MCP服务器的开发与部署。
2436 63
|
5月前
|
存储 安全 Linux
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
124 4
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件

热门文章

最新文章