通信协议设计的那些事儿

【前注】未完待续,当此段文字不在时,表示已完成。

曾经主导过公司某产品自用的通信协议设计开发以及性能优化,一直没有时间总结,趁近期闲暇间隙将该事情了结一下。我会抛开协议的实现细节,主要从设计开发的角度去探讨通信协议的设计要点,谈谈经验。

确定一下需求范围,我们设计的是基于不可靠协议(意味着需要容忍丢包)去实现一套根据ID地址进行寻址建立连接的高可靠传输协议。那么我们需要设计:地址表供寻址,链路表供管理链路,链路需要有包含了状态、控制、统计等信息的控制块,有限状态机,通信报文,流控,重传等等。

虽然需要设计和考虑的东西有很多,但是通信协议的核心设计只有两个,一是有限状态机设计,二是报文设计。其中有限状态机是整个协议的灵魂,重中之重,必须要先设计好完备的有限状态机后才可以继续进行后续的设计开发,尤其是对于报文设计而言,因为状态机的设计不当,往往会导致后面的返工,而且一不小心就是推倒重来的地步。

有限状态机的设计要领:必须所有状态闭环,强大的容错机制。所有状态闭环的意思就是说没有某个单向的状态点,许进不许出的那种,例如TCP协议的状态机,每个状态都是允许进入并且允许转变出去的,不会有哪个状态一旦陷入,无法退出的情况。

强大的容错机制就是指无论通信的双方处于状态机中任意的某一状态,都可以自行协商恢复建链通信。自行协商恢复可以是有协议报文交互的协商恢复,也可以是陷入异常状态等待状态机定时器超时重置链路。

另外要知道网络编程的特点就是YesNoUnknown,通信中交互信息Yes成功了,No失败了,或者Unknown不知道结果,而不像是函数调用返回那么明确地知道返回值是Yes成功或No失败。所以容错不仅仅考虑的是通信双方处于不同状态下的状态可恢复,甚至需要考虑到在正常的通信过程中,报文丢失后所引起的故障能否使链路陷入异常状态,这个异常状态能够使链路自愈。比如报文多次重传,链路进入的状态是否会使得链路永久重传,得不到恢复。

报文设计的原则是配合有限状态机完成工作。其中重点是报文头设计,报文头是什么?就是协议中固定携带的一段关于通信消息的信息描述结构。设计的主要要素有:

1)        
版本号:表示协议的版本,除非准备搞个一锤子买卖,不考虑后续协议的延伸和扩展的,请自便;

2)        
报文头大小:表示报文头结构的大小,为什么会要有这个东西呢?代码写死的大小不可以吗?是的,可以的,但它涉及到协议的扩展,当你预留的报文头字段全都发挥定义作用之后,是没法扩展的,至少扩展起来的代码实现有点烂;

3)        
消息大小:表示消息大小,主要作用有校验消息的完整有效性,同时可以快速定位消息末尾位置(对于加了校验码或者附属信息的情况下相当有用);

4)        
协议报文类型:表示当前的报文类型属性,通常的通信协议都肯定会有这么几种类型的,数据报文,控制报文,建链报文、心跳报文、探测报文等等。或者可以简单地划分为数据报文和控制报文,至于其他和链路控制相关的都统一归纳到控制报文当中,由控制报文去细分子类型。别小看类型设计,它奠定了后期的代码结构,比如细分了各种控制类型的,我可能需要用到
switch-case的结构去选择具体的处理分支,那么不同分支中是否可能会有重复的流程处理呢?重复代码多了是否会臃肿呢?是否会影响性能呢?这都是值得思考的。个人建议是,尽可能粗粒度划分报文类型,根据不同的报文类型的差异处理适当合并为某一类型,具体再根据处理差异细分子类型。

5)        
报文子类型:也就是基于报文类型进行作用功能细分的产物,这是可选的。甚至有必要的情况下还可以进一步基于子类型的设计之上,设置子子类型。虽然报文子类型通常是相对于控制类报文而言的,但是我们的数据报文可以复用该字段,设计为单片报文、组包报文、分片报文(首片、中片、尾片),至于控制报文的子类型则可以设计为状态报文、链路激活报文、链路重置报文等。

6)        
链路信息:指的是通信双方的地址
ID信息,如有必要可以考虑增加或者预留路由地址ID信息,有些不能直接送达的通信报文是需要接力一下的。

7)        
控制信息:指的是通信链路维护和控制信息,比如报文发送序列号、报文应答序列号、丢失报文的
gap重传信息、MTU协商、状态机定时器周期协商、报文响应标志。值得注意的是报文响应标志,它用于表示通信接收方接收到该标识位的消息后,必须给予响应回复。它需要合理应用,尤其是各种报文交互的过程中,需要注意起带动的交互消息,慎防双方空耗在相互间不断请求响应的报文中。

8)        
数据信息:用于指示当前传输的数据报文信息,比如当前组包报文打包进去的报文数量,或者当前分片报文的分片数量以及当前片的序列号。

报文头的各个字段的编排也很重要,往往会影响后面的编码实现,甚至会对性能造成一定的影响,这是我在协议的性能优化中深有体会的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注