最近因为工做上的须要(一方面是与底层与传感器进行数据交互,另外一方面是对RabbitMQ的AMQP协议的学习),接触了一些网络协议相关的内容。正好就二进制协议与文本协议的一些问题简单说一些。java
协议:就是一组你们约定俗成的契约,你们都遵照。而计算机领域的协议,大多指的就是网络协议。后端
网络协议:计算机网络中进行数据交换而创建的规则、标准或约定的集合。说直白点,就是你们约定XXX网络协议下的数据怎么接收,怎么处理,怎么发送等。数组
二进制协议(Binary protocol):安全
Wiki: A binary protocol is a protocol which is intended to be read by a machine rather than a human being, as opposed to a plain text protocol such as IRC, SMTP, or HTTP/1.1. Binary protocols have the advantage of terseness, which translates into speed of transmission and interpretation.
Binary protocol is also used in the context of a protocol between exactly two parties, in contrast to a multi-party protocol. Binary protocol, or binary collaboration have been used in the terminology of standards such as EbXML, HTTP/2 and EDOC.[1] An interface in UML [2] may also be considered a binary protocol.服务器
简单来讲,就是二进制协议在进行网络传输时,传输的并非相似JSON这样的文本文件,而是相似BSON这样的二进制数据。
(Java中字节流采用的是ASCII码,而字符流采用的是Unicode码)网络
TCP:一种面向链接的、可靠的、基于字节流的传输层通讯协议,由IETF的RFC 793定义。数据结构
首先,咱们从网络模型的角度来考虑。TCP位于传输层,接收上一层的数据,对数据进行必要的分割,并将数据交给网络层,且保证这些数据的准确到达(三次握手)。因此,做为传输层的协议,TCP主要任务是传输与数据分割。那么很明显,采用二进制数据进行传输时最好的选择。传输层可以充分发挥二进制协议空间占用小(带宽消耗低),可靠性高(提升数据传输的可靠性),运算规则简单(便于数据的分割等工做)等优势。并因为传输层特性,下降了其缺点所带来的影响。说到这里,不得不说层次架构是个好东西,其典型表明的网络模型,更是如此。其次,了解TCP报文结构的朋友想象一下。若是TCP不是二进制协议,而是一个文本协议,那么其中的TCP Flags,Checksum等的实现会不会变得冗余,繁琐。因此,TCP是一个二进制协议。与此同时,TCP协议也是二进制协议的一个典型表明。架构
其余:UPD,IP,PPP,Protobuf,MQTT,AMQP等典型例子类比分析便可,再也不赘述。ide
相对于文本协议而言,二进制协议的自定义更具区分度,数量也更多。缘由也很简单,正如以前所说,二进制协议相对文本协议扩展性更差,可读性更差,这也就形成其复用性不好。每每不一样产品,项目间的二进制协议差异也许不大(原本就是比较底层的东西,没有过高的复杂性),但就是不能共用(也许就是协议中,数据的标示符,命令字等区域位置,长度有所不一样)。因此,二进制协议的自定义较为常见。工具
以自身为例,我负责的物联网项目中的终端程序须要与不一样传感器进行交互。而大多第三方的硬件厂商并不会采用诸如MQTT这样的网络协议,他们每每会自定义一个二进制协议,来与上层通讯(毕竟硬件实现MQTT这样的标准化协议,也是须要成本投入的)。例如我解决交互的第一个传感器526,其实经过串口通讯(这个,有点古老)。它的数据帧是这样的:
很明显,这样的规定非常“死板”,Java中,经过RXTX监听对应串口,并接收数据数组(这里可能涉及到数据的粘包,拆包工做。固然,若是数据接收频次不高,而且不是连续数据,能够经过sleep或wait等来暂停一下,确保数据接收完毕)。以后,根据第三方厂商所给数据帧格式,对命令,数据域进行解析(这里就必须很死板地根据对应位置读取对应数据,另外数据域可能采用BCD码)。最后根据命令字,对数据进行相关操做。
这个时候,咱们再看一下,同一厂商下同一产品线,型号略有不一样的产品826,它的数据帧与前面的526其实差不过。
可是,二者的区别在于,前者数据域的每一个数据都是三个字节的,然后者则是四个字节的。因此得重写。固然,若是接入的第三方自定义协议越多,就越好作抽象,从而达到必定的复用(固然,效果确定是不能和文本协议相比较的)。
文本协议(Text-based protocol):
Wiki:A text-based protocol or plain text protocol is a communications protocol whose content representation is in human-readable format.
The immediate human readability stands in contrast to binary protocols which have inherent benefits for use in a computer environment (such as ease of mechanical parsing and improved bandwidth utilization).
简单来讲,就是文本协议在进行网络传输时,传输的是相似JSON,XML这样的文本文件,而不是二进制文件(就是0和1)
通常来讲,这个时候,就该有人要抬杠了。通常能够分为两种,这里咱们就HTTP这一文本协议为例子讨论。第一种,有人提出HTTP协议的底层依旧是0和1,它怎么就是文本协议了。答案就是一个协议是否是文本协议,与它在网络模型的上下层协议无关,只与自身相关。第二种,有人提出HTTP能够用来传输图片(写过相似NODE.JS服务器原始请求,就是返回值类型,须要专门指定。会明白图片传输是采用二进制的),那么HTTP还能算文本协议嘛。答案就是它是否是文本协议,取决于它是否可以利用文本的格式来进行通讯,很明显它能够,因此它是文本协议。这也避免有人拿telnet能进行二进制通讯来抬杠。固然,国外也有人提出是否是文本协议不取决于它可否对二进制数据进行编码(UTF,ASCII),而是取决于协议是围绕数据结构,仍是文本字符串。最后,上述HTTP协议是指HTTP1.1,而HTTP2是二进制协议(根据这点,国外那位的观点,须要稍做修改:在传输的数据是否具有数据结构)。
二进制协议的优缺点转换一下就OK了,不在赘述。
HTTP1.1:基于请求-响应模型,无状态,无链接的应用层协议。
其余:FTP,TELNET等。
乍一看,貌似平时你们开发的协议貌似大可能是二进制协议,什么RPC,AMQP,就连Kafka都是基于TCP自写的二进制协议。不过以前就说了,二进制协议缺少复用性,因此可能是确定的嘛。可是用得最多的仍是HTTP这样的文本协议。平时先后端进行的交互,就是基于HTTP的,也就是文本协议的。通常来讲,咱们直接用的都是文本协议,即便涉及二进制协议,也是对二进制协议进行了必定封装(如kafka的java API,AMQP的API)后的调用。
多数状况下,不少人能够写了好几年都碰不到几次二进制协议,可是一旦进了二进制协议的坑(一方面是物联网中与硬件交互,另外一方面是研究什么MQ的通讯协议啊),而后就只能说一句,真香。
好吧,开个玩笑。其实两种协议各有利弊,没有银弹,只有适用场景。说几个主要的考虑点,首先从成本(包含学习成本,时间成本等)来看,文本协议确定是优于二进制协议的,不然,也不会那么多人不了解二进制协议了。其次从效率(包括带宽等资源消耗,数据处理等)来看,二进制协议确定是优于文本协议的,不然,也不会那么多MQ采用二进制协议了。而后从可读性来看,文本协议确定是因为二进制协议的,固然这也带来了学习成本(包括熟悉二进制协议,如数据帧等)。最后从扩展性与安全性来看,二进制协议虽然有必定扩展性,致使开发的时间成本上升。但我认为若是数量较多,造成协议族效果,其实成本也就没那么高了(毕竟二进制协议中不少工具是通用的,数量优点也能够完成良好的抽象)。安全性方面,二进制协议有天生的优点(全是0和1),其编码规则只有收发双方了解,加解密也方便。