注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[RakNet] BitStream 实现分析  

2008-08-31 20:20:15|  分类: net_RakNet |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一般我们都将数据序列化为 byte stream 用于网络传输,比如 bool 也会占用 one byte。BitStream 则更进一步,将所有的数据都最优地序列化为 bit,比如 bool 只占用 one bit。
简单来说,即使消耗一些 cpu 来换更小的空间,从而减少网络传输的数据。

----------------------

其中一个 BitStream 的构造函数有个 _copyData 的参数,可以决定 _data 是否会被 memcpy 一遍。如果仅仅是 read data,其实并不需要 copy。 _copyData 这个参数的设计比较不错。
BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData );

----------------------

Read/WriteDelta();

Player.Hp = 10
Player.Mp = 20

假设协议是一次将发送玩家的 Hp, Mp 给客户端,此时,仅仅是 Hp 有变化,而 Mp 没有。例如:

bs.WriteDelta(Player.Hp, OldHp)
bs.WriteDelta(Player.Mp, OldHp)

则客户端读取的时候,可根据情况,判断是否需要更新数据。

if ( bs.ReadDelta(NewHp) )
   // modify hp
if ( bs.ReadDelta(NewMp) )
   // modify mp

实际写入 BitStream 的数据就会变为
true | data
false

如果数据变化,会多占用一个 bit,数据未变化时,则节约了很多。

----------------------

Read/WriteCompressed()

对一些特殊的数据,尽量压缩。BitStream 提供了
Read/WriteNormVector()
Read/WriteVector()
Read/WriteNormQuat()


下面说说数字的压缩:(对于 float, double 则特殊处理)

整个数字的压缩,实现与这个函数:
void BitStream::WriteCompressed( const unsigned char* input, const unsigned int size, const bool unsignedData );
总的来说,就是数字越小,占用的 bit 越少。
注意,如果写 bs.WriteCompressed(-3) 会占用很多 bit,因为内部调用时, unsignedData = true。

-----

unsigned int a = 15;
0F 00 00 00            // 下面从高位到底位进行处理

00 -> bit 1
3 x 00 = 111

0F & 0xF0 == 0x00        // 最后的 one byte,也会尝试压缩 0xF0 部分
0F = 1 1111

所以结果就是 1111 1111

-----

unsigned int a = 16;
10 00 00 00

3 x 00 = 111

10 & 0xF0 != 0x00        // 如果压缩失败,多占用 one bit
10 = 0 0001 0000

所以结果是 1110 0001 0000

-----

如果输入值是
20 01 00 00

2 x 00   => 11

01 != 00 => 0            // 不匹配,将剩余的 2 byte 直接 WriteBits()

20 01    => 0010 0000 0000 0001

结果为 1100 0100 0000 0000 001
  评论这张
 
阅读(1246)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017