文档章节

简单的文本协议、二进制协议

小车车
 小车车
发布于 2017/02/17 11:07
字数 1341
阅读 7
收藏 1

写网络程序躲不过协议,协议其实就是定义了消息的格式,以及消息是如何交换的。协议可简单可复杂,复杂精密如TCP协议,简单奔放如HTTP的协议。这里将我所接触到的协议稍微总结一下,最后抛出一个个人设计的简单通用的文本协议。

设计一个协议不是一件很容易的事情,尤其是当对设计的要求包含很好的描述性和可扩展性的时候。如果再将效率考虑在内,则更是件耗脑力的活。在继续讨论下去之前,先看看现有的一些协议吧。这里主要讨论的是应用层的协议,应用层的协议大多是请求响应模式(除了zeromq这个变态的家伙,后面再说),所以这里侧重讨论消息格式。

HTTP协议

这可能是大家接触得最多的协议了,HTTP协议是一个比较简单的基于文本的协议。消息格式基于文本,换行分隔键值串,键和值用冒号分隔,同时定义了一些标准的键和值。这个协议描述性教强——人类可读。扩展性强——加自定义的头很容易,也几乎不会有副作用(除了消息体积增加一点点)。但是,缺点就是标准定义的东西太多了,细节太多。解析较复杂。

memcached协议

memcached有两种协议,文本协议二进制协议,文本协议以换行表示一个请求结束。请求内部参数以空格分隔。为了二进制安全,在二进制数据前要加上长度这个参数,如set x 3 abc\r\n。

文本协议固然简单,可是当请求很小的时候,过多的协议本身的数据则显得浪费(比如每个HTTP请求只发送一个字母,可HTTP头可能有上百的字符,太浪费了),而且,server在接收到请求之后还要做文本解析,也耗cpu,于是memcached又推出了二进制协议,为了锦上添花,是的memcached更加高效。二进制协议的优点就是高效,因为所有信息都以最少的数据量来表达,且server解析请求时做的是数学比较而不是字符串比较,效率高很多。

memcached的协议比起HTTP来就轻得多了(当然,两者所面向的场景不一样,故这个比较没太大意义)。但是,也有缺点,就是扩展性较差,协议定得比较死,哪个位置上有哪些东西,是什么意义是定死的。所以,直接哪来用在不同的场景下不大现实。

redis协议

redis的协议也是文本协议,但是设计得比较小心和通用(我后面自己定义的协议深受其影响),在保证描述性的同时尽量减少协议本身的数据量,比如,在memcached的文本协议中,错误用“ERROR\r\n”来表示,而redis使用“-”来表示,用“:”开头的行表示整数等等。这样的设计结合了文本协议的简单和一部分二进制协议的高效。用在redis这个场合,很是适合。交换方式同样是请求响应。redis协议有一个缺点,就是,一个消息有多少参数是需要在开头指定的。不像HTTP协议用空行来表示结束。这就带来一个缺点,不好流水操作,也就是说消息必须在发送第一个字节之前被完全确定,因为第一个东西就是参数个数:-(。

上面讨论的基本都是文本协议,当然还有很多采用二进制协议的服务,如gearman、mysql等,二进制协议就相当于压缩版的文本协议,提高了传输效率,但是降低了描述性和灵活性(万一那个位置预留的位数不够就囧了)。

总的来说,这就是一个平衡的过程。如果消息体不是很小(比如每次只传一个字节的消息就很小了),那么采用文本协议还是值得的。毕竟文本协议简单,好扩展,利于调试(telnet就可以当客户端用),虽说消息是让计算机读的,但有时候也要人去看。所以,能用文本还是用文本吧。

简单文本协议

最后我定义了一个简单的基于文本的协议,叫做simpletp(Simple Text based Protocol),详细定义在这里http://simpletp.org,这个协议是为了简单的RPC而设计,结合了HTTP协议的灵活(以空行结束),redis协议的轻量(size+data)。但为了简单通用,没有采用redis的单字符表示类型的设计,因为这样就会引入额外的复杂性,如表示整数用“:”,那么浮点数、复数等等怎么办,干脆什么类型都没有,就简单的传输size+data串(有点类似zeromq,但是比zeromq做的事情少),而具体的类型则交由其他机制去处理,如protocol buffer。

© 著作权归作者所有

共有 人打赏支持
小车车
粉丝 4
博文 82
码字总数 72325
作品 0
深圳
程序员
TCP/IP协议整理

TCP/IP协议 TCP用于应用程序之间的通信 APP1<------TCP(双开工的通信)----->APP2 IP用于计算机之间的通信 IP是无连接的通信协议 TCP/IP 意味着 TCP 和 IP 在一起协同工作。 TCP负责应用软件...

cs_sharp
2016/02/23
35
0
基于 Java NIO 的异步 IO 框架 - BaseIO

BaseIO是基于java nio开发的一款可快速构建网络通讯项目的异步IO框架,其以简单易用的API和优良的性能深受开发者喜爱。 项目特色 支持协议扩展,已知的扩展协议有: Redis协议(仅作测试),示...

generallycloud
09/11
0
0
第十四章:实现自定义的编码解码器

14.1 编解码器的范围 我们将只实现Memcached协议的一个子集,这足够我们进行添加、检索、删除对象;在Memcached中是通过执行SET,GET,DELETE命令来实现的。Memcached支持很多其他的命令,但我...

李矮矮
2016/09/27
14
0
as3 与 服务器 关于2进制协议。

as3处理websocket或者给予文本的协议,是很简单,但我们服务器协议有很多是二进制的(文本的协议,对于手机客户端来说,流量有些大),as3需要处理字节流。 封装接口: readInt() writeInt(i...

木瓜瓜
2012/04/06
0
0
《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用

Spring目前提供了对RMI、 HttpInvoker、Hessian、Burlap及WebService等Remoting技术的集成。Spring屏蔽了这些实现技术的差异,用户只需开发简单的Java对象(Plain Old Java Objects,POJO)然后...

谜男amu
05/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Swift-系统默认UICollectionViewController的基本用法

不用xib创建时,需要重写 override init(collectionViewLayout layout: UICollectionViewLayout){} 在调用时需传 UICollectionViewLayout值,不然就会报错 let layout = UICollectionViewFlow......

west_zll
1分钟前
0
0
Spring Boot 最核心的 3 个注解详解

最近面试一些 Java 开发者,他们其中有些在公司实际用过 Spring Boot, 有些是自己兴趣爱好在业余自己学习过。然而,当我问他们 Spring Boot 最核心的 3 个注解是什么,令我失望的是鲜有人能答...

Java技术栈
2分钟前
0
0
Sqoop 增量导入导出及Job操作示例

增量导入 递增列的增量导入append # 第一次导入[root@node222 ~]# /usr/local/sqoop-1.4.7/bin/sqoop import --connect jdbc:mysql://192.168.0.200:3306/sakila?useSSL=false --table ac......

PeakFang-BOK
8分钟前
0
0
Thread中断的理解

★中断的理解:1)中断可以理解为线程的一个标识位属性;2)表示一个运行中的线程是否被其他线程进行了中断操作 中断好比其他线程向该线程打了个招呼,其他线程通过调用该线程的interrupt()...

karma123
16分钟前
0
0
App store 侵权投诉

App Store Content Dispute 侵权投诉 https://www.apple.com/legal/internet-services/itunes/appstorenotices/#?lang=zh...

壹峰
40分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部