这篇纯正满足本人的好奇心

我如同是一个在海边游玩的孩子,不断为拾到比通常更润滑的石子或更漂亮的 贝壳而欢欣鼓舞,而展示在我背后的是齐全未探明的真谛之海。牛顿

写本文的时候,想起高中物理课本的一句话:

我如同是一个在海边游玩的孩子,不断为拾到比通常更润滑的石子或更漂亮的贝壳而欢欣鼓舞,而展示在我背后的是齐全未探明的真谛之海。

那个时候不懂这句话,忙于刷分,现在纯正是为了本人的好奇心而探索一些问题,脑海中又开始复现这句话。本文的问题来自于后面的一篇文章:《HTTP学习笔记(三) HTTP/2》, 这篇文章里咱们提到了HTTP/2的几个特点:

  1. is binary, instead of textual
二进制代替了文本
  1. is fully multiplexed, instead of ordered and blocking
多路复用
  1. can therefore use one connection for parallelism
并行申请
  1. uses header compression to reduce overhead
压缩申请头,缩小耗费
  1. allows servers to “push” responses proactively into client caches
容许服务器被动推送响应进入客户端的缓存中

其实对于1我是不了解的,毕竟在计算机的世界都是“二进制”嘛,过后我的想法是难道是跟JDK解决String一样的操作,在JDK8之前,String自身是借助于char来存储的:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {    /** The value is used for character storage. */    private final char value[];}

到了JDK 8之后, JDK借助byte来存储字符串:

public final class String    implements java.io.Serializable, Comparable<String>, CharSequence,               Constable, ConstantDesc {    @Stable    private final byte[] value;}    

毕竟一个char占两个字节, 一个byte只占一个字节,因为我之前用程序连贯过充电桩,接管充电桩的报文,给的报文都是byte类型的,byte更小,像String就带了一些额定的信息,所以我猜测,是这个意义上的二进制,然而这只是猜测,我想过用抓包工具去验证我的猜测,然而发现抓包工具我用的并部署,再加上HTTP/2.0都是加密报文,抓包挺麻烦的,我也想过看HTTP Client的源码,然而这两个奏效都太慢了,最近偶尔翻看MongDB的文档,翻到了这方面的阐明,这个问题就有了答案。其实HTTP也对下面的二进制进行了解释:

Why is HTTP/2 binary?

Binary protocols are more efficient to parse, more compact “on the wire”, and most importantly, they are much less error-prone, compared to textual protocols like HTTP/1.x, because they often have a number of affordances to “help” with things like whitespace handling, capitalization, line endings, blank lines and so on.

二进制协定绝对于文本协定,比方HTTP/1.x ,解析效率、传输效率更高,有更好的容错性。还提供了一些机制能够帮忙解决空白字符、大小写、空行等等。

For example, HTTP/1.1 defines four different ways to parse a message; in HTTP/2, there’s just one code path.

例如,HTTP/1.1定义了四种解析数据的形式,然而在HTTP/2, 只有一种代码门路。

It’s true that HTTP/2 isn’t usable through telnet, but we already have some tool support, such as a Wireshark plugin.

尽管HTTP/2曾经不能再应用Telnet了,然而咱们也有其余工具的反对,比方 Wireshark plugin。

所以HTTP说本人是二进制的,潜台词是HTTP/2的数据包采取了高度结构化的格局,因为在计算机中,最终一切都是二进制模式存在。在HTTP/2中传输的数据会被格式化为帧(frame), 每个帧都会被调配一个流。HTTP/2的帧具备特定的格局,如下图所示:

 +-----------------------------------------------+ |                 Length (24)                   | +---------------+---------------+---------------+ |   Type (8)    |   Flags (8)   | +-+-------------+---------------+-------------------------------+ |R|                 Stream Identifier (31)                      | +=+=============================================================+ |                   Frame Payload (0...)                      ... +---------------------------------------------------------------+

在HTTP/2中,每个帧都由两局部组成: 帧头(9个字节),帧头是固定长度的,占据9个字节,蕴含了对于该帧的一些信息,比方长度、类型等。帧头前面是有效载荷,长度可变,取决于帧的类型和内容。这有点相似于TCP数据包,读取HTTP/2帧能够遵循定义好的过程(先读取数据长度,而后帧的类型)。相比之下,HTTP/1.1是由一个ASCII编码的文本行组成的非结构化格局,尽管这些文本最终将以二进制模式传输,然而基本上它是一串字符的流,而不是明确地被分为独立的帧。

HTTP/1.1的音讯通过一一字符地读取字符来解析,直到达到换行字符为止,这种形式有点凌乱,然而因为无奈晓得每行的长度,所以必须一一字符进行解决。对于HTTP注释的长度能够提前晓得,咱们能够在HTTP头里获知到这个信息。

这让我想起了MongDB的BSON,我想BSON中的binary的语义该当和HTTP/2的binary语义是对等的,在BSON标准的官网能够看到咱们的猜测是正确的:

BSON is a binary format in which zero or more ordered key/value pairs are stored as a single entity. We call this entity a document.

BSON是一种二进制格局,其中有零个或多个有序的键/值对被存储为一个繁多的实体,咱们将这个实体称之为文档。

上面是一个JSON和其对应的BSON格局的示例:

{"hello": "world"} →\x16\x00\x00\x00           // total document size 总的文档大小 算上大小字段自身\x02                       // 0x02 = type String hello\x00                  // field name 字段值\x06\x00\x00\x00world\x00  // field value 字段值\x00                       // 0x00 = type EOO ('end of object')

总结一下,在计算机中最终一切都是二进制格局,当咱们在数据格式中看到二进制时,咱们能够了解为这种存储构造是高度结构化的 , 读取效率更高,更为紧凑,将数据从新进行布局。