[小数]双精度浮点数:double 、8个字节。可表示范围:-/+1.7e308(精确到15位小数)
[字符串]string、 可变长度: 这个可以理解为char数组。由于其长度是可变动的,因此协议发送字符串时,前面会加一个长度字段,来表示后面有多少个字节表示字符串。
可以注意到上面的数据类型可表示范围有两种情况,标准术语是有符号和无符号,这块可以结合代码进行学习理解。
网络通讯中,往往需要考虑带宽的限制,减少不必要的消耗。因此会对协议的每个字段定义其选择哪种类型作为存储表示。例如购买道具时,道具ID可能选择int类型或者int64类型,其目的是要做到单服道具唯一(一个服的道具数量是很大的)。还有一些可能会选择string来存储,其目的是做到整个区唯一。对于道具数量可能更多选择char类型或short类型, 因为购买道具时数量一般不会太大。但如果是购买资源的数量,那这个类型选择可能就需要int了。
四、协议测试
1. 字段边界测试
购买物品数量,获得道具,卖出道具数量等等,数字往往都是用正数。
function sell_item(self,packet) local itemId = packet:readInt() local count = packet:readShort() -- 判断有没有这个道具 if bag not itemid then return end -- 判断道具数量 if self.bag[itemId].number >= count then self.bag[itemId].number = self.bag[itemId].number - count end end
local count = packet:readShort(),读取的数量如果不做负数检查,那么上面就会产生一个Bug,在功能测试的时候客户端有做输入限制,因此这个问题可能会被忽略。但对于一个千方百计获取非法收益的“玩家”来说,这就有机可趁了。那么我们做协议测试时就需要考虑了,比如short类型我们直接发0xFFFF,如果服务端是按照有符号来读取的,那么获得的就是是负数。
2、字段遍历测试
对每一个字段进行从最小值到最大值的逐步遍历测试。例如一个字符串“hello”,它的长度是short,十六进制表示如下:
00 05 68 65 6c 6c 6f
如果特意修改这个长度改成0x00FF或其他值,那么接收端在读取的时候可能就会出问题。对于长度改小,那么接收端获取的字符串内容可能就少了一部分,在继续的业务处理中可能无法正常处理;对于长度改大,那么接收端可能读取数据越界造成内存数据异常。
3、逻辑测试
1)限制条件测试
例如一个副本玩家等级需要满足30级才可进入。玩家等级不足时,往往客户端界面按钮会灰色显示且阻断玩家点击。这样就会造成一个假象现象,以为服务端有做限制。我们可以通过构造一个进入副本的协议包绕开客户端,直接发送给服务端来验证是否有做验证。
2)交互顺序测试
例如玩家之间交易会有一个锁定的过程,是否可以直接构造一个交易确认包,在不锁定的情况下就直接交易了。这样的漏洞会使“不法玩家”对其他玩家进行恶意交易欺骗,造成其他玩家的利益受损。
3)其他
测试中还有其他的测试方法,可以结合场景进行设计。
五、总结
协议测试是对功能测试的有效补充,做好协议测试可以减少异常情况和非法操作下的代码问题,从而加强功能的稳定性。协议测试使用的工具推荐使用WPE,当然有时候我们需要减少分析协议或降低测试人员的学习门槛而开发一些工具,后面的文章将介绍协议测试工具的开发。
源自公众号 游戏测试开发