消息分帧(字符串设计或协议设计)的两种形式

如果你读过Redis的源码,那么一定知道Redis的sds的设计。C语言中,字符串以 '\0' 结尾,printf 函数 遇到 '\0' 之后便会停止输出;而sds则是为字符串增加了一个长度,首先我们读取这个字符串长度为多少,然后 打印多少个字符。

这就是消息分帧中常见的两种形式:

  • Length prefixing 预先放置长度,这种形式就是在真正的字符串之前放置一个长度,以表明字符串的长度。例如 10helloworld。 这样做的好处是可以提前知道长度,然后再打印,获取字符串长度的时间复杂度为 O(1)。坏处是字符串长度有最大长度的限制, 而且由于不同的长度时,并不能全部使用到 int 所占用的位,所以可能会造成一定的空间浪费,但是也有解决方案,可以看redis 最新的sds设计。此外,这种形式的设计是二进制安全的。
  • Delimiters 分隔符,这种形式就和C语言中的一致,使用一个特殊的分隔符来代表终结。这种做法的好处在于节省空间,但是坏处也 很明显:非二进制安全;获取字符串长度的时间复杂度为 O(N)

这两种形式各有好坏。

前者在现实世界中的使用案例有Redis中的sds设计,HTTP/2协议,TCP协议,Redis通信协议等等多种协议; 后者在现实世界中的使用案例有UNIX系统中的文件(以EOF结束), C语言中的字符串(以\0结束)等。

实际使用中,我们需要根据实际的场景来决定使用哪一种。



微信公众号
关注公众号,获得及时更新

更多文章
  • NSQ源码分析
  • NSQ简明教程
  • 结合Redis与MySQL实现又快又好的数据方案
  • 程序员的MySQL手册(五):索引优化
  • 程序员的MySQL手册(四):索引设计
  • 程序员的MySQL手册(三):数据库设计
  • Linux窗口管理器下的截图
  • Go设计模式:facade模式和观察者模式
  • 程序员的MySQL手册(二): 监控与benchmark
  • Go设计模式: 责任链模式
  • 我们真的需要这么复杂的技术栈吗?
  • Go设计模式:装饰器模式
  • 程序员的MySQL手册(一): 安装,基本配置
  • ElasticSearch学习笔记
  • Go设计模式:composite模式