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

如果你读过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结束)等。

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



更多文章
  • 怎么使用ViewModel 和 RecyclerView
  • deeplink结合路由处理扩展App的能力
  • Android手动挡MVVM
  • 来电拦截方案
  • 你好,2021!
  • gRPC鉴权方案
  • Golang里数据库migration方案
  • Android SwipeRefreshLayout左右滑动冲突的解决
  • Android调用gRPC的两个小工具函数
  • Android上结合kotlin使用coroutine
  • gRPC错误处理
  • Java collection的结构
  • 为啥Redis使用pipelining会更快?
  • 通过阳台种菜实现蔬菜自由
  • 从GORM里学习到的panic处理方式