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

本文涉及的产品
性能测试 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进行规格选择与性能压测。
相关文章
|
1月前
|
运维 Prometheus 监控
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
|
1月前
|
Linux iOS开发 网络架构
如何使用 Ping 命令监测网络丢包情况?
如何使用 Ping 命令监测网络丢包情况?
162 48
|
1月前
|
安全 Windows
【Azure Cloud Service】在Windows系统中抓取网络包 ( 不需要另外安全抓包工具)
通常,在生产环境中,为了保证系统环境的安全和纯粹,是不建议安装其它软件或排查工具(如果可以安装,也是需要走审批流程)。 本文将介绍一种,不用安装Wireshark / tcpdump 等工具,使用Windows系统自带的 netsh trace 命令来获取网络包的步骤
69 32
|
11天前
|
Web App开发 网络协议 安全
网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark
Wireshark是一款开源和跨平台的抓包工具。它通过调用操作系统底层的API,直接捕获网卡上的数据包,因此捕获的数据包详细、功能强大。但Wireshark本身稍显复杂,本文将以用抓包实例,手把手带你一步步用好Wireshark,并真正理解抓到的数据包的各项含义。
48 2
|
29天前
|
缓存 Ubuntu Linux
Linux环境下测试服务器的DDR5内存性能
通过使用 `memtester`和 `sysbench`等工具,可以有效地测试Linux环境下服务器的DDR5内存性能。这些工具不仅可以评估内存的读写速度,还可以检测内存中的潜在问题,帮助确保系统的稳定性和性能。通过合理配置和使用这些工具,系统管理员可以深入了解服务器内存的性能状况,为系统优化提供数据支持。
34 4
|
2月前
|
存储 监控 网络协议
服务器压力测试是一种评估系统在极端条件下的表现和稳定性的技术
【10月更文挑战第11天】服务器压力测试是一种评估系统在极端条件下的表现和稳定性的技术
135 32
|
2月前
|
缓存 监控 测试技术
服务器压力测试
【10月更文挑战第11天】服务器压力测试
103 31
|
2月前
|
自然语言处理 机器人 Python
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
ChatPaper是一个基于文本生成技术的智能研究论文工具,能够根据用户输入进行智能回复和互动。它支持快速下载、阅读论文,并通过分析论文的关键信息帮助用户判断是否需要深入了解。用户可以通过命令行或网页界面操作,进行论文搜索、下载、总结等。
67 1
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
|
1月前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
|
2月前
|
SQL 分布式计算 NoSQL
大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行
大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行
50 4