貌似合理的网络包协议
最近有个小项目,很快的开始,似乎也能很快的完工。就一个不大不小的游戏,2d 的,图象引擎是成熟的,然后我就这这段日子对 lua 的热情,用 lua 把原来写的 C++ 图象引擎做了个封装。用起来感觉良好,UI 部分封装的也不错。游戏逻辑用 lua 驱动貌似很方便。一度幻想着哪天把它开源出去,没准可以成为 lua 开发 2d 游戏的准标准。想想可能性不大,纯当意淫了。
小项目比较能锻炼队伍,所以我做为基本封装就跟新同事上课了。看着别人做程序心里痒痒的,做不出来急急的。恨不得什么都自己代劳。
其中一个同事的工作安排是网络协议的封装,争取用 lua 封装的好用一些。
老实说,我对网络编程的实战经验非常有限,总共不超过 1 万行代码。写的可以运行的可以称之为程序的东西不超过 5 个。其中一部分是基于 UDP 协议的,而这次这个小项目打算用 TCP 协议。我不禁想起大话的通讯协议,首先一个字节的 type 和接下来两个字节的数据包长度信息。
当初,我对这个协议颇有微辞。因为 tcp 是一个流协议,如果统一用数据包长度来分包,再由 type 来 dispatch 逻辑的话,最合理的应该是先把长度信息放在前面,让最底层的代码把数据流分割成数据包,然后就可以把整个数据包交给网络无关的层次去处理。
这次设计协议的时候,希望可以用 lua 脚本来描述每个协议,用 C++ 代码将网络数据包解析成 lua 的一个 table,这样,lua 就可以很方便的处理网络传送过来的数据了。
非阻塞模式下,socket api 处理 TCP 协议,只有在读单个字节时才能看成一个原子操作。这样当我们的数据包长度大于一个字节时,都不能默认它是一次可以读到的。所以,处理网络数据流的过程一般用一个状态机来实现。这个状态机可以实现的很简单,长度+类型+内容这种格式,我们可以看成状态机的三个状态。 程序的主逻辑里,我们只需要不停的调用状态机的处理过程,就可以完成对网络数据的处理。
我按这个思路设计程序的时候却发现,长度完全是个纯粹的冗余信息。因为,如果我们用脚本定义好了每种协议的格式,那么长度已经可以根据协议的 type 推导出来。大部分的协议格式是由定长的元素构成,最终它本身也是定长的。有些元素是不定长的,例如 string 和 array 。那么整个的长度还是可以根据上下文获得。至于处理后一种,无非是增加了状态机处理程序的一点点难度而已。
这样,我不再在数据包头放上包的长度。
Comments
Posted by: admin | (47) May 12, 2017 01:31 PM
Posted by: windmeup | (46) September 2, 2011 11:33 AM
Posted by: Anonymous | (45) July 25, 2010 05:51 AM
Posted by: Anonymous | (44) August 30, 2009 02:45 PM
Posted by: tigerdx8 | (43) November 13, 2007 03:54 PM
Posted by: tgame | (42) March 26, 2007 08:45 PM
Posted by: Anonymous | (41) November 7, 2006 12:35 PM
Posted by: wangdali | (40) October 15, 2006 04:47 AM
Posted by: colin | (39) June 8, 2006 09:50 PM
Posted by: xue23 | (38) February 24, 2006 10:23 AM
Posted by: cj2528 | (37) February 23, 2006 09:21 AM
Posted by: Cloud | (36) February 21, 2006 01:18 PM
Posted by: cj2528 | (35) February 21, 2006 10:55 AM
Posted by: Cloud | (34) February 15, 2006 01:10 PM
Posted by: viewlg | (33) February 14, 2006 10:45 PM
Posted by: Cloud | (32) February 14, 2006 01:10 PM
Posted by: nandou | (31) February 14, 2006 11:11 AM
Posted by: Cloud | (30) February 13, 2006 01:20 PM
Posted by: 2002thinking | (29) February 11, 2006 08:55 PM
Posted by: coder | (28) January 18, 2006 03:27 PM
Posted by: Cloud | (27) January 18, 2006 02:54 PM
Posted by: KxjIron | (26) January 18, 2006 02:28 PM
Posted by: Cloud | (25) January 18, 2006 01:45 PM
Posted by: zlong | (24) January 18, 2006 11:45 AM
Posted by: wonna | (23) January 18, 2006 09:32 AM
Posted by: KxjIron | (22) January 18, 2006 08:49 AM
Posted by: Atry | (21) January 18, 2006 01:39 AM
Posted by: hifee | (20) January 18, 2006 01:26 AM
Posted by: hifee | (19) January 18, 2006 01:20 AM
Posted by: Cloud | (18) January 18, 2006 12:22 AM
Posted by: KxjIron | (17) January 18, 2006 12:17 AM
Posted by: Cloud | (16) January 17, 2006 11:57 PM
Posted by: wonna | (15) January 17, 2006 11:43 PM
Posted by: Cloud | (14) January 17, 2006 11:34 PM
Posted by: wonna | (13) January 17, 2006 09:51 PM
Posted by: analyst | (12) January 17, 2006 09:50 PM
Posted by: wonna | (11) January 17, 2006 09:47 PM
Posted by: wonna | (10) January 17, 2006 09:41 PM
Posted by: Cloud | (9) January 17, 2006 08:56 PM
Posted by: Anonymous | (8) January 17, 2006 08:28 PM
Posted by: Cloud | (7) January 17, 2006 07:28 PM
Posted by: analyst | (6) January 17, 2006 06:15 PM
Posted by: Anonymous | (5) January 17, 2006 05:14 PM
Posted by: Atry | (4) January 17, 2006 02:42 PM
Posted by: Cloud | (3) January 17, 2006 12:58 PM
Posted by: wonna | (2) January 16, 2006 10:49 PM
Posted by: KxjIron | (1) January 16, 2006 10:20 PM