络游戏数据包的特点一个是数据量大,一个是非常多的小数据包。一个高性能网络库中一个数据包从接收到应用层处理最好减少拷贝次数,尽管内存数据拷贝是非常快速的但数据收发量特大时就不能不考虑了。另外特别多的小数据包也是网络游戏的特点,比如在WINDOWS下大多采用IOCP,但如果针对每个数据包都去调用一次SEND,在极端情况下会导致IOCP中的队列满而导致发送不成功的情况,解决办法即是将多个小数据包拼成大包发送,减少SEND的调用次数。
本文介绍的环形队列即可针对上面两种情况做出优化,在高并发大数据量的情况下能取得较好的效果。需要规定下收发的数据包的最大长度,游戏数据包大多都是小数据包,个别太长的也可以在逻辑层进行控制拆分。环形队列就不做过多介绍了,这种扩展的环形队列即是在一般环形队列的最后增加一个最大数据包大小的长度
一个连接设一读一写两个环形缓冲。
读缓冲:当投递读操作时可以直接取相应缓冲区的写指针和适当长度,待读操作完成时再在此缓冲区修改写指针的位置。在需要处理数据包的时候根据每个数据包的长度和读指针的位置进行处理,直接将读指针交由逻辑层处理即可,2如果数据包长度不超过尾部的两个数据区则直接按情况1处理 否则将头部的数据区拷贝到最尾部的扩展的区域中 然后将读指针交由逻辑层处理,待逻辑层处理数据包后再修改读指针位置。
写缓冲: 当逻辑层中有数据发送时并不是立刻将数据SEND,而是写到写缓冲中,待需要处理这个连接的SEND的时候从写缓冲中取读指针,及相应的大小
网络库中大多底层采用多个工作线程的方法,采用环形缓冲也可以避免锁缓冲区。