HTTP2 协议初识

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTTP2 协议初识相关的知识,希望对你有一定的参考价值。

参考技术A   RFC: https://tools.ietf.org/html/rfc7540

RFC 中英文对照: https://github.com/fex-team/http2-spec/blob/master/HTTP2%E4%B8%AD%E8%8B%B1%E5%AF%B9%E7%85%A7%E7%89%88(06-29).md

O'Reilly : https://hpbn.co/http2/

SPDY: http://www.chromium.org/spdy/

随着Web应用日渐广泛,复杂程度和重要性也在不断的增长,也因此对开发人员和用户带来了负担,HTTP2 支持所有的HTTP/1.1的核心特征,提供了HTTP语义的传输优化,并且在各方面做到更高效。

HTTP2 是运行在TCP或者SSL协议之上,属于应用层的协议。HTTP2.0消息包以二进制帧的形式进行封装。

Stream : 已经建立连接的双向字节流,用唯一ID标示,可以传输一个或多个消息

Message :逻辑上的HTTP消息,请求或者响应,可以包含多个 frame

Frame:HTTP2 通信的最小单位,二进制头封装,封装HTTP头部或body

HTTP2是把一个HTTP数据包分成多个帧发送,每个帧有一个二进制头,并把HTTP分成多个独立小帧,多个帧组成一个Message在流中发送。不同流的帧有可能交错到达,帧的报文头中标示了属于哪一个流。

HTTP2的最小数据单位是帧,所有帧以9字节的帧头并跟着0-16,383字节的数据。

Length: unsigned 24-bit integer,最大值为 2^24(16384),指的是不包括头部的部分

Type:帧的类型

Flags:为帧类型保留的8字节字段有具体的布尔标识

R:1位的保留字段

Stream Identifier:31字节的流标识符。0是保留的,标明帧是与连接相关作为一个整体而不是一个单独的流。

帧主体的结构和内容完全取决于帧类型。

HTTP2 有以下十种帧类型:

Pad Length : 8位,可选,只在设置了PADDED标记时呈现。表示帧填充的字节为单位的长度。

Data : 应用数据。

Padding : 填充字节不包含任何应用语义值。填充字节在发送时设为0,接收时忽略。

DATA 帧定义了以下的 Flags:

END_STREAM (0x1): 位1,表示当前帧是相应流发送的最后一帧。设置时流进入半封闭或关闭状态。

PADDED (0x8): 位4,表示Pad Length 字段启用与否。

Pad Length:8位可选,在设置PADDED 标记时呈现。表示帧填充的字节为单位的长度。

E : 1位可选,在优先级标记设置时呈现。表示用于标识流依赖是否是专用的。

Stream Dependency : 31位可选,在优先级标记设置时呈现。流依赖的流的标识符。

Weight : 8位可选,在优先级标记设置时呈现。流的8位权重标记,1-256的值。

Header Block Fragment : 报头块。

Padding : 填充字节

HEADERS 帧定义了以下的 Flags:

END_STREAM (0x1) : 位1,标识是此发送端对流发送的最后报头区块。设置这标记使流进入半封闭状态。

END_HEADERS (0x4) : 位3,表示帧包含了整个的报头块,且后面没有延续帧。 END_HEADERS为0的报头帧后面必须跟着延续帧。

PADDED (0x8) : 位4,表示Pad Length字段会呈现。

PRIORITY (0x20) : 位6,优先级标记(E), 流依赖及权重字段将会呈现。

E : 1位标记,指示流的依赖是专有的。

Stream Dependency : 流所依赖流的31位标识符。

Weight: 流的权重(8位)。1-256的权重值。

RST_STREAM 帧由一个32位整数标记错误码,指明流被终止的原因。

RST_STREAM 帧必须与流相关联,就是说stream id 不能为 0x0

RST_STREAM帧绝对不能在流处于“空闲”状态下发送。

载体包含0或多个参数,每个包含一个16位标识以及一个32位的值。

1)设置帧由两个终端在连接开始时发送,连接生存期的任意时间发送。

2)设置帧的参数将替换参数中现有值,不能识别的忽略。

3)设置帧总是应用于连接,而不是一个单独的流。流ID必须为0;

SETTINGS 帧定义了以下的 Flags:

ACK (0x1) : 位1,表示设置帧被接收端接收并应用。如果设置了ACK,设置帧的载体必须为空。

SETTINGS_HEADER_TABLE_SIZE (0x1) : 发送端通知远端报头压缩表的最大承载量。初始值是4,096个字节。

SETTINGS_ENABLE_PUSH (0x2) : 用来关闭服务器推送。0时不能发送PUSH_PROMISE。1表示可以推送。

SETTINGS_MAX_CONCURRENT_STREAMS (0x3) : 标明发送端允许接收端创建的最大并发流的数量。没有限制(<100) 。 0值阻止新流的创建。

SETTINGS_INITIAL_WINDOW_SIZE (0x4) : 表示发送端流量控制的初始窗口大小(字节)。初始值是65,535。 影响所有流的窗口大小.

SETTINGS_MAX_FRAME_SIZE (0x5): 接收最大帧大小。初始值为2^14 (16,384)字节,最大值为2^24-1 or 16,777,215字节。

SETTINGS_MAX_HEADER_LIST_SIZE (0x6): 可接收的header列表长度(字节),基于非压缩的列表大小。

1) 被推送的流并不需要按照顺序使用。

2) 接收端可以给推送端返回一个RST_STREAM拒绝接收。

Pad Length : 8位,只在PADDED标记设置时才呈现。

R : 1bit保留位。Padding : 填充字节。

Promised Stream ID : 31位整数表示终端准备发送的流标记。

Header Block Fragment : 包含请求头字段的报头区块。

PUSH_PROMISE 帧定义了以下的Flags:

END_HEADERS (0x4) : 位3, 表明帧包含了整个报头区块。

PADDED (0x8) : 位4, 表明Pad Length字段是已设置。

PING 帧定义了以下的Flags:

ACK (0x1) : 位1表示PING帧是一个PING响应。

1)PING帧可以被任何终端任何时刻发送。

2)PING帧必须在载体中包含一个8字节长度的数据。

收到不含ACK的PING帧必须发送一个有ACK的PING响应,带相同的载荷。PING响应应设置比其他帧更高的优先级。流ID为0,不和任何流关联;

可以由客户端或服务端发送。发动端将忽略连接上流标示符大于Last-Stream-ID的流。

接收端接收到超时帧后不能在这个连接上打开新流,可以创建新连接。

终端在关闭连接之前总是应当发送一个超时帧;

适用于连接而不是特定的流。流标识符必须是0x0,否则错误处理;

连接关闭前小于或等于标识符上的流没有完全关闭的,重试请求;

小于或等于最后流标识符的流可能仍然能成功完成,保持连接在打开状态直到正在处理的流全部处理完成。

在发送超时帧后,发送端能丢弃流标识符大于最终流标识的流的帧。但任何修改流状态的帧不能被忽略。

超时帧包含一个32位错误码,包含关闭连接的原因。

1) 可以作用单独的流(ID!=0) 或 整个连接(ID==0)

2) 所有类型的流量控制都是逐跳的(hop-by-hop), 中介端不会转发

3) 流量控制只适用于Data帧

4) 一个保留字节,一个31位整数( 发送端被允许传输的字节数,它的大小是接收端的缓存能力的衡量)。

5) 流和连接的初始值都是65535;流的窗口大小可以用SETTING帧设置大小SETTINGS_INITIAL_WINDOW_SIZE;

6) 通过设置窗口大小,可能导致窗口大小为负数(当前有10字节数据,设置为5字节,则剩余-5字节的长度)。

只要流上前一帧是不带END_HEADERS的HEADERS帧、PUSH_PROMISE帧或者不带有END_HEADERS标记的CONTINUATION帧,可以发送任意多个延续帧。

CONTINUATION 帧定义了以下的Flags:

END_HEADERS (0x4) : 位3,指示帧是否是报头区块的终止。 如果END_HEADERS位没有被设置,这个帧必须跟着另一个延续帧。

h2:基于TLS之上构建的HTTP/2,作为ALPN的标识符,两个字节表示,0x68, 0x32,即https

h2c:直接在TCP之上构建的HTTP/2,缺乏安全保证,即http

在不知道服务器是否支持http2的情况下,可以利用http的升级机制发送试探包

1、客户端发起请求

2、服务器不支持 http2,直接按照 http/1.1响应

3、服务器支持 http2,通知客户端切换到http2

4、服务器发送的第一个http2帧,必须为SETTINGS帧做为连接序言

5、客户端接收到101响应后,也必须发送一个序言作为响应,其逻辑结构:

6、客户端可以马上发送请求帧或其它帧过去,不用等待来自服务器端的SETTINGS帧

7、任一端接收到SETTINGS帧之后,都需要返回一个包含确认标志位SETTIGN作为确认

8、其它帧的正常传输

1、客户端和服务器端TLS层协商

2、客户端发送连接序言(同上表示,PRI + SETTINGS)

3、接收到客户端连接序言之后,服务器端发送连接序言

4、双方各自确认SETTINGS帧

5、其它帧的正常传输

1、客户端必须首先发送一个连接序言,其逻辑结构:

2、发送完毕序言之后,客户端可以不用等待来自服务器端响应,马上发送HTTP/2其它帧

3、服务器端接收到客户端的连接序言之后,需要发送一个SETTINGS帧作为连接序言

4、任一端接收到SETTINGS帧之后,都需要返回一个包含确认标志位SETTIGN作为确认

5、其它帧的正常传输

1、HTTP/1.1在建立建立之后,只需要发送请求报文数据

2、HTTP/2客户端需要在连接建立之初马上发送一个连接序言过去,然后才是正常请求

3、两端(客户端+服务器端)的两次完整的连接序言+确认的交互流程,多了两次往返过程

Android之Http通信——1.初识Http协议

Android之Http通信——1.初识Http协议

引言:


今天是六一儿童节,先在这里给各位超龄儿童说声节日快乐哈~( ╯□╰ ),小猪也象征性地给群里的小朋友们派了红包…嗯,忙碌的五月最终过去了,做毕设,写论文,拍毕业照,答辩,辞职。各种各样的事,也算忙完了,好吧。小猪如今又在一家新的公司上班了。第三间公司了。你们肯定会认为小猪三心二意是吧,毕竟才差点儿相同毕业就换了那么多家公司,然后可能问我。”小猪你什么时候跳第四间公司”,哈哈,应该不会了哈,怎么说呢,事实上我还是非常专一的,毕竟我才刚毕业。我还临时不须要去养家糊口。赡养老人,并且我没女朋友。哈哈~所以趁着年轻,选择适合自己的生长的土壤。学多点本事,工资事实上没什么,真的,能学到东西才是关键,等真正有本事了。那个时候就能够谈工资了,比方我这个公司的大牛(只是这周已跳槽到魅族了)。第一次感觉到大牛的气息,B格真心高。自愧不如,人家自己写组件。推送,各种代码封装。各种设计模式,并且会服务端,測试。IOS…有点看小说里。一个刚入门的小学徒看到一个宗师级别的高手时那种感觉,以前。小猪自卑了几天,一直在想,我真的能接手他的项目吗?或者说看懂他代码?又或者我是否能写出这样的代码?那几天,整个人都非常浮躁。各种负面情绪,连代码都看不进去;后来不经意看到了一个讲设计的TED演讲,标题是:《怎样成为一名优秀的设计师:罗子雄》,这个虽然不是说编程的,可是事实上非常多东西都是相通的。分为两个阶段:入门&准专业级,”你们希望你们希望成为一名设计师。但不止如此,你们希望成为的是一名优秀的设计师。但没有人生下来就是优秀的,没有人生下来就是牛逼的,没有人生下来就会UI设计。会平面设计。会网页设计。”。从入门到准专业级,我们须要多少经验?”格拉德威尔在《异类》一书中指出:“人们眼中的天才。并不是卓越非凡,而是付出了持续不断的努力,一万小时的锤炼是不论什么人从平庸变成超凡的必要条件。

”一万小时。也就是说你每天工作8小时的时间,每周工作5天,你须要5年。你无需天才,无需智商过人,无需三头六臂,无需头上长角,你仅仅须要持续的、坚持的努力,有正确的方法,就能够在设计领域,一个专业中独当一面。”看完,整个人就阔让开朗了,心也就静下来了,对啊,人家做多久,我做多久了?人家做五年了,我仅仅是个刚毕业的实习生,不会非常正常啊,非常多东西,急不来。每天有规划。一步一个脚印,日积月累。坚持5年。或者不用。我也能成为一个准专业级的大牛是吧,所以何必自卑呢~恩呢,心灵鸡汤的东西就讲这么多吧。喝多了酒没作用了,视频还是不错的,有兴趣能够看看哈,好了,从今天開始小猪会在学习公司项目的同一时候总结相关的一些东西,然后分享给大家,第一个章节解说的是Android中的Http通信,先叙述下Http相关的一些概念,然后讲下Android上发送Http请求的两种方式:HttpUrlConnection与HttpClient,然后使用retrofit框架封装我们的HTTP请求,最后用RxJava实现响应式编程,实现网络的异步请求调用。当然小猪也是在学习其中。假设有什么写得不正确的地方。欢迎指出,万分感激~


正文:

1.Http是什么鬼?

①名词解析:

  • hypertext transfer protocol(超文本传输协议),TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEBserver之间交换数据的过程。

    client连上webserver后,若想获得webserver中的某个web资源,需遵守一定的通讯格式,HTTP协议用于定义client与webserver通迅的格式。

②Http 1.0 与 Http 1.1的差别:

  • 1.0协议。client与webserver建立连接后,仅仅能获得一个web资源!
  • 1.1协议,同意client与webserver建立连接后,在一个连接上获取多个web资源!

PS:如今大部分的都是用的Http 1.1协议的~

③Http请求的工作流程:

这里先介绍两个名词,SYN和ACK

  • SYN(synchronous):TCP/IP建立连接时使用的握手信号
  • ACK(Acknowledgement):确认字符。确认发来的数据已经接受无误

接着说下TCP/IP三次握手的概念:

  1. client发送syn包(syn = j)到server,进入SYN_SEND状态,然后等待server确认
  2. server收到syn包,确认客户的syn(ack = j + 1),同一时候在自己也发送一个SYN包(syn=k),
    即SYN + ACK包,server进入SYN_RECV状态
  3. client收到SYN + ACK包,想server发送确认包ACK(ack = k +1),发送完毕后,client与服务端
    进入ESTABLISHED状态。完毕三次握手,然后两者開始传送数据

假设你认为复杂的话,看图想想你就有个大概印象了,三次握手示意图例如以下:

技术分享

Http操作的流程:

  1. 用户点击浏览器上的url(超链接)。Web浏览器与Webserver建立连接
  2. 建立连接后。client发送请求给server,请求的格式为:
    统一资源标识符(URL)+协议版本(通常是1.1)+MIME信息(多个消息头)+一个空行
  3. 服务端受到请求后。给予对应的返回信息,返回格式为:
    协议版本 + 状态行(处理结果) + 多个信息头 + 空行 + 实体内容(比方返回的HTML)
  4. client接收服务端返回信息,通过浏览器显示出来,然后与服务端断开连接;当然假设中途某步错误发生的话,错误信息会返回到client,并显示,比方:经典的404错误

好吧,No pic you say a jb,有图有真相,以下我们用HttpWatch来抓下包(当然,你也能够直接用Chrome f12),这里測试的站点是小猪学校的教务系统:输入账号password后,发送登陆请求,相关信息头。至于相关的信息头,我们下节再具体解说~:

HTTP请求包含的内容:

技术分享

HTTP响应包含的内容:

技术分享

④Http请求的几种方式:

我们看到上面我们发送http请求的方式是POST,它和GET在我们平时开发中使用较多,以下我们就罗列出全部的请求方式吧:

  • Get:请求获取Request-URI所标识的资源
  • POST:在Request-URI所标识的资源后附加新的数据
  • HEAD 请求获取由Request-URI所标识的资源的响应信息报头
  • PUT:请求server存储一个资源,并用Request-URI作为其标识
  • DELETE:请求server删除Request-URI所标识的资源
  • TRACE:请求server回送收到的请求信息,主要用于測试或诊断
  • CONNECT:保留将来使用
  • OPTIONS:请求查询server的性能。或者查询与资源相关的选项

好吧,除了GET和POST其它的,笔者也没用过,所以,这里仅仅区分GET和POST的差别:

  • GET:在请求的URL地址后以?的形式带上交给server的数据。多个数据之间以&进行分隔,但数据容量通常不能超过2K,比方:http://xxx?

    username=…&pawd=…这样的就是GET

  • POST: 这个则能够在请求的实体内容中向server发送数据,传输没有数量限制
  • 另外要说一点,这两个玩意都是发送数据的,仅仅是发送机制不一样,不要相信网上说的”GET获得server数据,POST向server发送数据”!!
    另外GET安全性非常低。Post安全性较高,可是运行效率却比Post方法好,一般查询的时候我们用GET。数据增删改的时候用POST。!

⑤Http状态码合集:

  1. 100~199 : 成功接受请求,client需提交下一次请求才干完毕整个处理过程
  2. 200: OK,client请求成功
  3. 300~399:请求资源已移到新的地址(302,307,304)
  4. 401:请求未授权。改状态代码需与WWW-Authenticate报头域一起使用
  5. 403:Forbidden。server收到请求,可是拒绝提供服务
  6. 404:Not Found,请求资源不存在,这个就不用说啦
  7. 500:Internal Server Error。server发生不可预期的错误
  8. 503:Server Unavailable。server当前不能处理client请求。一段时间后可能恢复正常

⑥Http协议的特点

好吧。这些东西知道就能够了,小猪就不自己慢慢扣了,直接复制粘贴哈~

  1. 支持客户/server模式。
  2. 简单高速:客户向server请求服务时。仅仅需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与server联系的类型不同。

    由于HTTP协议简单,使得HTTPserver的程序规模小,因而通信速度非常快。

  3. 灵活:HTTP同意传输随意类型的数据对象。正在传输的类型由Content-Type加以标记。

  4. 无连接:无连接的含义是限制每次连接仅仅处理一个请求。server处理完客户的请求,并收到客户的应答后。即断开连接。採用这样的方式能够节省传输时间。
    5.无状态:HTTP协议是无状态协议。

    无状态是指协议对于事务处理没有记忆能力。

    缺少状态意味着假设兴许处理须要前面的信息,则它必须重传。这样可能导致每 次连接传送的数据量增大。还有一方面。在server不须要先前信息时它的应答就较快。

⑦OSI七层协议&TCP四层协议;

恩,这个我们知道就能够了,兴许有须要的话再深入了解,我们的HTTP请求是出于第七层:应用层的,
大家知道就能够了,另外最好记下这七层,对了,一到三层是用于创建两个网络设备间的物理连接的。
而四到七层主要负责互操作性,背熟就好,面试说不定问下呢,是吧。哈哈~

OSI七层协议图&TCP四层模型图:

技术分享

另外小猪查相关资料的时候,发现一个B格更高的总结图,有兴趣的能够慢慢研究:
技术分享

贴下原文链接,想刨根问底的能够看下:

OSI七层模型具体解释

总结:

好吧,由于时间比較仓促,毕竟仅仅能下班的时候写写,可能有点乱,望体谅,有时间会又一次捋一捋思路。部分内容參考的慕课网的”Android HTTP通信“视频的 内容,有兴趣能够去慕课看看。恩。最后总结下本节的东东吧:

  1. 介绍了下HTTP协议的一些概念、
  2. 简单的说了下HTTP 1.0 和HTTP 1.1的差别
  3. HTTP请求的流程,包含SYN和ACK的概念,TCP/IP三次握手,HTTP操作的流程,HTTP请求的几种几种方式,HTTP状态码合集,以及HTTP协议特点
  4. OSI七层协议图&TCP四层模型图

本节都是一些概念性的东西,了解了解就好。下一节,我们来研究不同的响应头。我们服务端通过设置不同的响应头来控制浏览器的一些行为,比方页面从定向。定时刷新。提示文件下载等,敬请期待~好了。洗澡睡觉。明天继续上班哼(ˉ(∞)ˉ)唧~

PS:刚舍友路过,问我一晚上在扣什么?写代码么,我说写博。然后他又问这能赚钱么?我说不能。然后他说,那写了有个卵用…我也不知道怎么跟他解释,每一个人的看法。价值观不同吧。我喜欢写博,虽然我不是大牛,我写出来的东西B格也没人家高。可能都是一些基础的东西。虽然如此,我还是愿意在下班吃完饭后,埋头码字一个晚上,不积跬步何以千里。持续的。坚持的努力,再加上正确的方法,小猪也有成为大牛的那一天的,另外,把摸索出来的方法写出来,又能够方便后来者。何乐而不为呢?是吧!

与各位攻城狮们共勉~加油










以上是关于HTTP2 协议初识的主要内容,如果未能解决你的问题,请参考以下文章

HTTP2.0协议

彻底掌握Http2协议

为啥说 HTTP2 是二进制协议?

HTTP2.0协议被曝4个高危漏洞,可致服务器崩溃

5GC基础自学系列 | 5GC协议系列之SBI接口HTTP2

HTTP402- 深入理解http2.0协议,看这篇就够了!