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

本文涉及的产品
性能测试 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进行规格选择与性能压测。
相关文章
|
2月前
|
运维 Prometheus 监控
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
|
3月前
|
机器学习/深度学习 人工智能 运维
企业内训|LLM大模型在服务器和IT网络运维中的应用-某日企IT运维部门
本课程是为某在华日资企业集团的IT运维部门专门定制开发的企业培训课程,本课程旨在深入探讨大型语言模型(LLM)在服务器及IT网络运维中的应用,结合当前技术趋势与行业需求,帮助学员掌握LLM如何为运维工作赋能。通过系统的理论讲解与实践操作,学员将了解LLM的基本知识、模型架构及其在实际运维场景中的应用,如日志分析、故障诊断、网络安全与性能优化等。
101 2
|
16天前
|
缓存 负载均衡 监控
HTTP代理服务器在网络安全中的重要性
随着科技和互联网的发展,HTTP代理IP中的代理服务器在企业业务中扮演重要角色。其主要作用包括:保护用户信息、访问控制、缓存内容、负载均衡、日志记录和协议转换,从而在网络管理、性能优化和安全性方面发挥关键作用。
51 2
|
2月前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
53 2
|
2月前
|
弹性计算 监控 数据库
制造企业ERP系统迁移至阿里云ECS的实例,详细介绍了从需求分析、数据迁移、应用部署、网络配置到性能优化的全过程
本文通过一个制造企业ERP系统迁移至阿里云ECS的实例,详细介绍了从需求分析、数据迁移、应用部署、网络配置到性能优化的全过程,展示了企业级应用上云的实践方法与显著优势,包括弹性计算资源、高可靠性、数据安全及降低维护成本等,为企业数字化转型提供参考。
63 5
|
2月前
|
缓存 Ubuntu Linux
Linux环境下测试服务器的DDR5内存性能
通过使用 `memtester`和 `sysbench`等工具,可以有效地测试Linux环境下服务器的DDR5内存性能。这些工具不仅可以评估内存的读写速度,还可以检测内存中的潜在问题,帮助确保系统的稳定性和性能。通过合理配置和使用这些工具,系统管理员可以深入了解服务器内存的性能状况,为系统优化提供数据支持。
46 4
|
3月前
|
存储 监控 网络协议
服务器压力测试是一种评估系统在极端条件下的表现和稳定性的技术
【10月更文挑战第11天】服务器压力测试是一种评估系统在极端条件下的表现和稳定性的技术
164 32
|
3月前
|
缓存 监控 测试技术
服务器压力测试
【10月更文挑战第11天】服务器压力测试
110 31
|
3月前
|
存储 安全 数据可视化
提升网络安全防御有效性,服务器DDoS防御软件解读
提升网络安全防御有效性,服务器DDoS防御软件解读
65 1
提升网络安全防御有效性,服务器DDoS防御软件解读
|
3月前
|
自然语言处理 机器人 Python
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
ChatPaper是一个基于文本生成技术的智能研究论文工具,能够根据用户输入进行智能回复和互动。它支持快速下载、阅读论文,并通过分析论文的关键信息帮助用户判断是否需要深入了解。用户可以通过命令行或网页界面操作,进行论文搜索、下载、总结等。
76 1
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)