`
wanxiaotao12
  • 浏览: 457793 次
  • 性别: Icon_minigender_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。

分享到:
评论

相关推荐

    文本及二进制通信命令

    文本 二进制 通信 协议,文本 二进制 通信 协议,命令转换说明书

    老生常谈文本文件和二进制文件的区别

    下面小编就为大家带来一篇老生常谈文本文件和二进制文件的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    HTTP上传和下载C++封装类支持GET、POST多种方式

    通过HTTP协议上传文本和二进制数据、支持POST方式、支持GET方式;

    lisp-binary:一个轻松读取和写入复杂二进制格式的库

    LISP-BINARY提供了DEFBINARY宏,您可以用它声明某些二进制数据的结构,无论是文件格式,网络协议还是您拥有的文件。 它在本质上类似于和 ,但功能更强大。 快速演示: (defpackage :instant-compressor (:use :...

    java嵌入matlab源码-binary-parsing:解析二进制数据结构(例如文件格式,网络协议或比特流)的通用工具列表

    (Python):用于解析和构建数据结构(二进制或文本)的库。 以声明的方式定义您的数据结构 (DSL,C / C ++,Zeek):用于网络协议和文件格式的下一代解析器生成器 (Python):逐字段查看和编辑二进制流。 渴望...

    wap:[WIP]事件驱动的WebAssembly二进制和文本格式解析器

    事件驱动的WebAssembly二进制和文本解析器 特征 事件驱动 WebAssembly二进制解析 WebAssembly文本解析 部分解析 文字格式转储 WASM规格 格式正确的UTF-8字节序列 基于Unicode标准11.0第3.9节,表3-7。 代码...

    论文研究-基于扩展前缀树的协议格式推断方法.pdf

    对未知网络协议进行协议格式推断在网络安全领域具有重要意义。现有的协议格式推断方法存在时间复杂度高、精确度较低等问题。...实验结果表明,该协议格式推断方法对于文本协议和二进制协议都能够取得理想的推断效果。

    mime协议(详细)

    但是,由于图片和声音等内容是非ASCII码的二进制数据,而RFC822邮件格式只适合用来表达纯文本的邮件内容,所以,要使用 RFC822邮件格式发送这些非ASCII码的二进制数据时,必须先采用某种编码方式将它们“编码”成可...

    Web应用安全:HTTP协议的由来.pptx

    而超文本说明传输的数据首先是文本,不是”二进制包“,不是杂乱无章的数据,而是具有意义的可以被浏览器等直接识别和处理的文本。而显然单纯的文本不能满足用户的全部需求,现在的需求形式多样五花八门,所以文本的...

    C#实现WebSocket源码(c#写的服务端html写的客户端)

    WebSocket 协议在2008年诞生,2011年成为国际标准。...(4)可以发送文本,也可以发送二进制数据。 (5)没有同源限制,客户端可以与任意服务器通信。 (6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

    MIME协议(中文版).doc

    但是,由于图片和声音等内容是非ASCII码的二进制数据,而RFC822邮件格式只适合用来表达纯文本的邮件内容,所以,要使用 RFC822邮件格式发送这些非ASCII码的二进制数据时,必须先采用某种编码方式将它们“编码”成可...

    basexx:通过各种二进制到文本编码方案对数据进行编码

    一个简单的实用程序,可通过许多通用的二进制到文本编码方案之一对数据进行编码/解码。 该程序从Coreutils项目提供的basenc命令中得到启发。 BaseXX的主要目标是对basenc进行改进,并了解不同的二进制到文本编码...

    GSMt通信搜索

    GSM规范]对短消息传输定义了三种控制协议:即二进制协议(块模式),基于字符的AT命令接口协议(文本模式)和基于字符的十六进制编码二进制传输块接口协议(PDU 模式)。 块模式 (Block mode) 是使用二进制编码来传输...

    智能家居安全监控

    GSM规范]对短消息传输定义了三种控制协议:即二进制协议(块模式),基于字符的AT命令接口协议(文本模式)和基于字符的十六进制编码二进制传输块接口协议(PDU 模式)。 块模式 (Block mode) 是使用二进制编码来传输...

    spring-websocket-5.05-stomp-:spring-websocket-5.05 基于stomp协议

    spring-websocket-5.05-stomp-spring-websocket-5.05 基于stomp协议WebSocket协议定义了两种类型的消息,文本和二进制,但其内容未定义。 为客户端和服务器定义了一种协商子协议的机制 - 即更高级别的消息传递协议,...

    websocket实现聊天小demo

    WebSocket 在握手之后便直接基于 TCP 进行消息通信,只是 TCP的基础上的一层非常轻的封装,它只是将TCP的字节流转换成消息流(文本或二进制),至于怎么解析这些消息的内容完全依赖于应用本身。

    jBaseZ85:ZeroMQ Base-85编码的Java实现。 Base85是二进制到文本的编码库

    二进制到文本编码的基本需求来自通过已设计为仅携带人类可读文本的现有通信协议通信任意二进制数据的需求。 这些通信协议可能仅是7位安全的(并且在此范围内避免了某些ASCII控制代码),并且可能需要在某些最大间隔...

    H.248协议中文版

    H.248协议消息编码采用二进制或文本方式(由于文本方式具有很强的可读性,目前工程上都采用的是文本方式)

    mux-demux-stream:二进制文本流的复用器和解复用器

    使用单个多路复用器或多路分解器多路复用和多路分解多达八个二进制/文本流。 每个数据块前面都带有五个字节的标头,包括通道ID和有效载荷长度。 1个字节(通道ID) 4个字节(有效载荷长度) 可变长度的原始有效载荷...

    Android-对OkHttp3请求库简单封装适配Json-Rpc调用协议

    json-rpc是基于json的跨语言远程调用协议,比xml-rpc、webservice等基于文本的协议传输数据格小;相对hessian、java-rpc等二进制协议便于调试、实现、扩展,是非常优秀的一种远程调用协议。

Global site tag (gtag.js) - Google Analytics