接触了一段时间的网游封包设计,有了一些初步的思路,想借这篇文章总结一下,同时也作个记录,以利于以后更新自己的思路。
网络游戏的技术研发,分为三个主要的方面:服务器设计,客户端设计,数据库设计。而在服务器和客户端之间实现游戏逻辑的中介则是游戏数据包,服务器和客户端通过交换游戏数据包并根据分析得到的数据包来驱动游戏逻辑。网络游戏的实质是互动,而互动的控制则由服务器和客户端协同完成,协同就必然要依靠数据来完成。
当前网络游戏中的封包,其定义形式是各种各样的,但归纳起来,一般都具有如下要素:封包长度,封包类型,封包参数,校验码等。
封包长度用于确定当前游戏数据包的长度,之所以提供这个数据,是因为在底层的TCP网络传输中,出于传输效率的考虑,传输有时会把若干个小的数据包合并成一个大的数据包发送出去,而在合并的过程中,并不是把每一个逻辑上完整的数据包全部合并到一起,有时可能因为这种合并而将一个在逻辑上具有完整意义的游戏数据包分在了两次发送过程中进行发送,这样,当前一次的数据发送到接受方之后,其尾部的数据包必然造成了“断尾”现象,为了判定这种断尾的情况以及断尾的具体内容,游戏数据包在设计时一般都会提供封包长度这个信息,根据这个信息接受方就知道收到的包是否有断尾,如果有断尾,则把断尾的数据包与下次发过来的数据包进行拼接生成原本在逻辑意义上完整的数据包。
封包类型用于标识当前封包是何种类型的封包,表示的是什么含义。
封包参数则是对封包类型更具体的描述,它里面指定了这种类型封包说明里所必须的参数。比如说话封包,它的封包类型,可以用一个数值进行表示,而具体的说话内容和发言的人则作为封包参数。
校验码的作用是对前述封包内容进行校验,以确保封包在传递过程中内容不致被改变,同时根据校验码也可以确定这个封包在格式上是不是一个合法的封包。以校验码作为提高封包安全性的方法,已经是目前网游普遍采用的方式。封包设计,一般是先确定封包的总体结构,然后再来具体细分有哪些封包,每个封包中应该含有哪些内容,最后再详细写出封包中各部分内容具体占有的字节数及含义。
数据包的具体设计,一般来说是根据游戏功能进行划分和圈定的。比如游戏中有聊天功能,那么就得设计客户端与服务器的聊天数据包,客户端要有一个描述发言内容与发言人信息的数据包,而在服务器端要有一个包含用户发言内容及发言人信息的广播数据包,通过它,服务器端可以向其他附近玩家广播发送当前玩家的发言内容。再比如游戏中要有交易功能,那么与这个功能相对应的就可能会有以下数据包:申请交易包,申请交易的信息包,允许或拒绝交易包,允许或拒绝交易的信息包,提交交易物品包,提交交易物品的信息包,确认交易包,取消交易包,取消交易的信息包,交易成功或失败的信息包。需要注意的是,在这些封包中,有的是一方使用而另一方不使用的,而有的则是双方都使用的包。比如申请交易包,只可能是一方使用,而另一方会得到一个申请交易的信息包;而确认交易包和提交交易物品这样的数据包,都是双方在确定要进行交易时要同时使用的。封包的设计也遵从由上到下的设计原则,即先确定有哪些功能的封包,再确定封包中应该含有的信息,最后确定这些信息应该占有的位置及长度。一层层的分析与定义,最终形成一个完善的封包定义方案。在实际的封包设计过程中,回溯的情况是经常出现的。由于初期设计时的考虑不周或其它原因,可能造成封包设计方案的修改或增删,这时候一个重要的问题是要记得及时更新你的设计文档。在我的封包设计中,我采用的是以下的封包描述表格进行描述:
封包编号 功能描述 对应的类或结构体名 类型命令字 命令参数结构体及含义
根据游戏的功能,我们可以大致圈定封包的大致结构及所含的大致内容。但是,封包设计还包含有其它更多的内容,如何在保证封包逻辑简洁的前提下缩短封包的设计长度提高封包的传输速度和游戏的运行速度,这也是我们应该考虑的一个重要问题。一般情况下,设计封包时,应该尽量避免产生一百字节以上的封包,多数封包的定义控制在100字节以内,甚至20-50字节以内。在我所定义的封包中,多数在20字节以内,对于诸如传递服务器列表和用户列表这样的封包可能会大一点。总之一句话,应该用尽可能短的内容尽可能简洁清晰地描述封包功能和含义。
在封包结构设计方面,我有另一种可扩展的思路:对封包中各元素的位置进行动态定义。这样,当换成其它游戏或想更换当前游戏的封包结构时,只要改变这些元素的动态定义即可,而不需要完全重新设计封包结构。比如我们对封包编号,封包类型,封包参数,校验码这些信息的开始位置和长度进行定义,这样就可以形成一个动态定义的封包结构,对以后的封包移植将会有很大帮助,一个可能动态改变封包结构的游戏数据包,在相当程度上增加了外挂分析封包结构的难度。
在进行封包设计时,最好根据封包客户端和服务器端的不同来分类进行设计。比如大厅与游戏服务器的封包及游戏服务器与游戏客户端的封包分开来进行设计,在包的编号上表示出他们的不同(以不同的开头单词表示),这样在封包的总体结构上就会更清晰。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/blacksource/archive/2009/05/26/4218542.aspx