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

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

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



更多文章
  • 长任务系统如何处理?
  • macOS/Linux 编译 InputLeap
  • 使用开源软KVM - synergy-core
  • 解决 macOS 终端hostname一直变化问题
  • KVM 共享 Intel 集成显卡
  • PromQL 备忘
  • 读《格鲁夫给经理人的第一课》
  • 读《打开心智》
  • 为什么要把复杂的联表操作拆成多个单表查询?
  • 红包系统的设计
  • 2022年终总结
  • MySQL Index Condition Pushdown Optimization
  • Go mod 简明教程
  • OpenWRT 使用 Android/iOS USB 网络
  • 搭建旁路由