开发者社区> 青衫无名> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

糟糕的应用层通信协议设计

简介:
+关注继续查看

去年和今年分别参与了两个公司的项目,这两个项目都涉及到了通信方面的程序设计,或者是以太网络通信,或者是串口通信。凡是通信就必须要有通信协议,个人认为协议的设计是个非常严肃的工作,需要理解业务需求和掌握基本的协议设计知识。但是从这两个项目来看,其协议的设计可以说是 糟糕到了极点。下面就其糟糕的设计之处予以批判。

1 糟糕设计之一:消息格式“包头+数据+包尾”

与UDP不同,TCP通信属于流式通信,没有消息边界,所以需要应用层自行对报文进行界定分离。实际项目1中,包头为{{两个字节,包尾为}}两个字节,例如{{t=123}}。其格式为:

开始边界+消息1+结束边界+开始边界+消息2+结束边界+开始边界+消息3+结束边界+....

由于TCP是安全的传输层协议,除非特别需要,应用层无需再做校验。消息边界只需要一个标识即可,基本格式为:

消息1+边界+消息2+边界+消息3+边界+...

无论从节约网络带宽,还是从简化报文解析代码,第一种设计都是非常的愚蠢!

无独有偶,项目2中基于串口的通信应用层协议也采用了这种设计格式。

当问其设计人员为何如此设计时,说一直就是这么设计的,自己也不知道这么设计的原因,还美滋滋地说一直没有什么问题,真想揍他一拳。

2 糟糕设计之二:用结构体代码而不是文本描述消息结构

项目2中,根本无协议的描述文本,只有一个包含结构体定义的头文件供协议的使用者参考。

通信就会涉及到多个机器,所以通信协议必须要能跨平台。而我们知道

struct A
{
char x;
int y;
};

在不同编译器,不同平台,不同编译选项下会有不同的二进制布局。况且协议使用者也可能看不懂C系语言代码。更搞笑的是,头文件中竟然没有强制结构体单字节对齐。

问到协议的设计者设计思路时,说我们公司一直这样啊,一直没问题啊。之所以没有问题,是因为使用这个协议的所有机器都是同一CPU型号,同一开发环境,同一操作系统。

3 糟糕设计之三:传送二进制浮点数

浮点数的二进制格式并不是只有一种,不同平台采用不同的方式存放。这要比大端小端的整数差别更加严重。所以跨平台传送二进制浮点数是非常不安全的。而在项目2中,消息中大量使用了二进制浮点数。

要传送浮点数,通常有两种解决方式:

文本化。也就是传送描述浮点数的字符串,我们知道字符串是完全跨平台的,尤其是在UTF-8这样全球统一字符编码的情况下。

转换为整数。例如1.2,可以用整数12代替,只是要规定单位为0.1即可。

4 糟糕设计之三:大量备用字段

项目二的消息结构体类似如下:

struct A
{
char name[16];
int age;
int spare1;
short spare2;
short spare3;
int spare4;
};

大量的备用字段充斥在结构体中。少量的备用字段可以理解,如此大量的后备力量,真是深远谋虑啊。真不知道协议使用者在看到spare时会不会吐。如果真的需要这么多备用字段,完全可以重新定义一个消息结构了。

5 糟糕设计之四:照猫画虎的握手和校验

握手和校验是保证安全完整通信的基本手段,但是其实现却非常不简单,看看TCP的实现代码就知道了,需要考虑各种异常情况。项目二中串口设备和主机之间照猫画虎地定义了一个握手协议。开机后 设备向主机一直发送AA,主机收到AA后向设备发送AA,设备收到AA后向主机发送55,主机收到55后向设备发送55。这个简单的握手存在很多问题,随便说几个:

完全没有必要握手。一般的串口设备无需知道主机的工作状态,主机如果想了解设备状态,发个询问报文即可。

如果主机发送AA后程序退出,那么串口设备永远也等不到来自主机的55。

如果主机中途关掉,在运行时可能收到来自串口设备的AA,而此时的AA其实只是消息报文的一个字节,而不是握手信号。

只要仔细想想,还有很多类似的情况需要处理。而且实际使用过程中,确实发生了上面的情况,致使必须重启串口设备或主机。

还是项目2中,基于UDP的应用层协议自行设计了校验。其实这也无可厚非,比如著名的tftp就是这样的协议。只是设计者考虑不周,各种问题频出,最终的结果是这些校验字段根本就没有实际使用,白白浪费了网络带宽。需要说明的是,这个协议的设计者还是国内很大的一家公司,当然是国企,你懂的


作者:smstong

来源:51CTO

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
网络聊天程序的设计与实现
网络聊天程序的设计与实现
0 0
408王道计算机网络强化——传输层和应用层(下)
408王道计算机网络强化——传输层和应用层
0 0
数据通信系统一些概念
数据通信系统一些概念
0 0
一文搞懂I2C协议-硬件基础
I2C总线是由飞利浦在80年代初设计的,以允许位于同一电路板上的组件之间能够轻松通信。其大大简化了电路的设计,早期的电视机中很多地方用到了I2C这种通信方式。飞利浦半导体于2006年迁移到了NXP。I2C名称翻译为“ Inter IC”。有时,该总线称为IIC或I²C总线。I2C总结的基本的特征
0 0
【计算机网络】应用层 : 网络应用模型 ( 应用层概述 | 客户端 / 服务器 模型 | P2P 模型 )
【计算机网络】应用层 : 网络应用模型 ( 应用层概述 | 客户端 / 服务器 模型 | P2P 模型 )
0 0
应用层/安全层/传输层如何进行协议选型?
应用层/安全层/传输层如何进行协议
541 0
《分布式系统:概念与设计》一3.3.4 协议
本节书摘来华章计算机《分布式系统:概念与设计》一书中的第3章 ,第3.3节,(英) George Coulouris Jean DollimoreTim Kindberg Gordon Blair 著 金蓓弘 马应龙 等译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
725 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
典型业务逻辑漏洞挖掘
立即下载
面向服务的可预期网络
立即下载
思科软件定义访问:实现基于业务意图的园区网络
立即下载