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

本文涉及的产品
性能测试 PTS,5000VUM额度
简介: 网络游戏前后端通信的消息协议始终是基于制定的规则,即发送端使用什么样的方式进行序列化,接收端就需要使用对应的方式进行反序列化,只有这样才能保证发收双方能够正常“交流” 消息协议的组成离不开基础数据类型,这些数据类型包括单字符(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)


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


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

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
相关文章
|
9天前
|
运维 Prometheus 监控
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
|
1月前
|
存储 监控 网络协议
服务器压力测试是一种评估系统在极端条件下的表现和稳定性的技术
【10月更文挑战第11天】服务器压力测试是一种评估系统在极端条件下的表现和稳定性的技术
112 32
|
1月前
|
缓存 监控 测试技术
服务器压力测试
【10月更文挑战第11天】服务器压力测试
83 31
|
1月前
|
自然语言处理 机器人 Python
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
ChatPaper是一个基于文本生成技术的智能研究论文工具,能够根据用户输入进行智能回复和互动。它支持快速下载、阅读论文,并通过分析论文的关键信息帮助用户判断是否需要深入了解。用户可以通过命令行或网页界面操作,进行论文搜索、下载、总结等。
51 1
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
软件测试中的人工智能:改变游戏规则的革新
在这篇技术性文章中,我们将深入探讨人工智能(AI)如何彻底改变了软件测试领域。从自动化测试到智能缺陷检测,AI不仅提高了测试的效率和准确性,还为软件开发团队提供了前所未有的洞察力。通过具体案例,本文揭示了AI在软件测试中应用的现状、挑战及未来趋势,强调了技术创新在提升软件质量与开发效率中的关键作用。
|
1月前
|
SQL 分布式计算 NoSQL
大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行
大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行
41 4
|
1月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
69 4
|
1月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
55 3
|
1月前
|
弹性计算 安全 Linux
阿里云国际版使用ping命令测试ECS云服务器不通的排查方法
阿里云国际版使用ping命令测试ECS云服务器不通的排查方法
|
1月前
|
分布式计算 监控 Hadoop
Hadoop-29 ZooKeeper集群 Watcher机制 工作原理 与 ZK基本命令 测试集群效果 3台公网云服务器
Hadoop-29 ZooKeeper集群 Watcher机制 工作原理 与 ZK基本命令 测试集群效果 3台公网云服务器
40 1
下一篇
无影云桌面