知识卡片

定长包头+可扩展包体的协议设计范式

普通读书笔记卡

内容

在[[IM应用层协议三种范式的取舍对比,及移动端为何应避开XMPP]]描述的二进制协议实践中,一种被反复验证有效的折中设计是:用定长二进制包头负责传输和解析效率,用可扩展的变长包体负责业务扩展性和可读性——包头本身不携带业务含义,只承担”这个包是什么、有多长、要不要处理”这类元信息;包体则可以自由选择文本、XML甚至protobuffer等格式来承载具体业务数据,包头和包体的职责被清晰地切开。一个典型的16字节定长包头包含:Version(版本号,用于兼容不同协议版本)、magic_num(魔法数字,一段约定好的特殊字节序列,放在包头或包尾,用来校验这段数据有没有发生错位或丢包——如果收到的报文在约定位置读不到这个魔法数字,就说明传输过程出了问题)、command(命令号,用于区分心跳包、业务包、密钥交换包等不同类型的报文)、len(包体长度,告诉接收方要读取多长的包体数据)。这个范式的普适价值在于,它把”如何让协议解析得快”和”如何让协议能持续扩展”这两个经常互相冲突的目标,分别下放给包头和包体两个独立的部分去解决,而不是试图用一种格式同时满足两种诉求——这正是文本协议和纯二进制协议各自的短板:前者扩展性好但解析慢,后者解析快但扩展性差,定长包头+可扩展包体的组合把两者的优点分别装进协议的两段里。

参考来源

- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.4 从零开始搭建高可用IM系统"节,"2.4.2 协议设计"(源文件:_epub-src/OEBPS/Text/Chapter2_4_3.xhtml) - 结论依据:原文说明"常见的做法是定长二进制包头,可扩展变长包体可以使用文本、XML等……包头负责传输和解析效率,包体与业务无关,负责保证扩展性",并逐项列出包头四个字段(Version/magic_num/command/len)的作用,直接支撑本卡片结论。 - 原始内容:常见的做法是定长二进制包头,可扩展变长包体可以使用文本、XML等……包头负责传输和解析效率,包体与业务无关,负责保证扩展性……对于定长包头(16个字节),有:前4个字节是Version……magic_num……command(命令号)……len(包体长度)。