HTTP 协议css
HTTP 协议是TCP/IP 网络协议中的应用层协议。算法
URL - 统一资源定位符浏览器
DNS 的做用 将域名 转为 IP 地址缓存
在发送HTTP 协议以前要创建TCP 链接,HTTP 是创建在TCP 链接之上的服务器
HTTP 1.1 版本默认开启Keep-alive,创建一次TCP 链接,能够重复使用网络
HTTP 请求的构建架构
创建TCP 链接后须要构建HTTP 报文,其报文大概分为三个部分并发
第一部分:请求行socket
第二部分:首部post
第三部分:正文实体
第一部分:请求行
方法有几种类型:
Get,获取资源,一般是一个网页,也多是一个JSON 字符串。
Post,主动告诉服务器一些信息,这些信息放到实体中,正文的格式一般是JSON。
Put,向指定的资源位置上传新内容, 但HTTP 的服务器一般不容许上传文件,因此在实际应用中,Post一般用来建立一个资源,Put 用来修改一个资源。
Delete,用来删除资源的。
第二部分:首部字段
首部是key value,经过冒号分隔。一般保存重要字段。
例如,Accept-Charest,表示客户端能够接受的字符集。
例如,Content-Type 指出正文的格式,若是咱们进行Post的请求,若是正文是JSON,,那么这个值就是JSON。
缓存的使用,缓存网页中静态的部分,例如图片等。这样能够在更新数据时没必要每次都刷新整个页面。
这个架构图以下所示:
HTTP头里的 Cache-control 是用来控制缓存的。客户端发送的请求中有max-age 指令时,要判断资源的缓存时间是否比指定的时间小,若是大于指定时间客户端就要从新下载了。
If-Modified-Since 也是关于缓存的。若是服务器的资源更新了,客户端就应该下载最新的资源。
HTTP 的报文构建好以后,浏览器如何把它交给下一层,传输层。本质上也是用Socket,只不过这些在浏览器中作好了。
HTTP 请求的发送
一、TCP 层会将 源地址和目标地址 信息放到IP 头里,并把它和报文一块儿交给IP 层传输。
二、IP 层要查看目标IP地址和源IP地址在不在同一个网段
若是在发送ARP 协议获取,目标IP地址的MAC 地址,让后将源MAC 地址和目标MAC 地址放到MAC头中,发送便可。
若是不在同一网段,仍是要发送ARP 协议获取网关的MAC 地址,将网关的MAC 和 源MAC 地址放到MAC 头中,发送出去。
三、网关收到包后查看目标IP地址,根据路由协议找下一个路由器,获取下一个路由器的MAC,而后将包发给它。
四、路由器这样一跳一跳的最终到达目标局域网。最后一跳的路由器发现目标IP 就在本身的某一个出口的局域网上。因而在这个局域网上发送ARP 协议,获取目标IP 的MAC 地址,将包发走。
五、目标机器发现MAC 地址符合,将这个包接收,查看IP地址也符合,再查看TCP 的头中的序列号,若是这个包是本身未接收的,就放入接收缓存中,而后回复ACK。
六、TCP 头里还有端口号,指明是哪一个应用须要接收的包,这个应用就是HTTP 服务器。服务器查看HTTP 层的消息,是get就返回一个网页,是Post 就建立一个新资源。
HTTP 返回的构建
下面这张图是HTTP1.1 版本的返回报文。
返回报文也是分为三个部分:状态行、首部、实体。
一、状态行中有,HTTP 版本;状态码就是202,404这些。短语会说一下出错缘由。
二、首部仍是 key value。这里面,Retry-After表示客户端在多长时间再尝试一下。Content-Type表示,返回的是HTML 仍是JSON。
三、构造好HTTP 报文后,仍是有socket发送出,先交给TCP层,TCP层会将HTTP报文分为一个个小段(由于这是一个网页,一个包发不了),而后是IP层,把刚才的过程反向走一遍。
HTTP 2.0
HTTP 1.1 的弊端:
在应用层以纯文本的形式通讯。
每次通讯都要带完整的HTTP头。
不考虑pipeline 模式的话,每次的过程都是一去一回。实时性、并发性存在问题。
HTTP 2.0 解决了 HTTP1.1 的不足:
对HTTP 的头进行压缩,在客户端和服务端创建key value 表,对相同的头只传输表的索引。
将一个TCP 的链接分为多个流,每一个流有本身的ID,和双向通道,有优先级。
将传输消息分为更小的消息和帧,并对它们采用二进制传输。让这些消息和帧在多个流中同时传输。这些帧发送时不按顺序,在接收端从新组装。
Header 帧用于传输Header 内容,并开启一个新的流;Data 帧用于传输正文实体,多个data 帧属于同一个流。
假设咱们的页面要发送三个独立的请求,一个获取css,一个获取js,一个获取图片jpg。若是使用HTTP1.1 就是串行。但若是是HTTP2.0,就能够在一个链接里并行。以下图所示:
HTTP2.0 将三个请求变成三个流,将数据分帧,乱序发送到一个TCP 链接中。
HTTP 2.0 解决了HTTP1.1 队首阻塞问题。HTTP1.1 要想作到多通道并行,须要经过pipeline 机制创建多条TCP 链接来实现。
QUIC 协议
HTTP2.0 也是基于TCP 协议实现的,TCP 协议是有顺序的。虽然HTTP2.0 是多个stream 传输,每一个流之间的数据并没有关联,流与流之间不须要顺序。
这就像一条大河中航行多个船队,每一个船队能够有本身的顺序,可是在入港口的时候却要求和本船队不相干的船只排好顺序再进港同样。
因而Google 将TCP 切换到UDP,构建了一个QUIC 协议。
机制一:自定义链接机制
TCP 重连机制太麻烦,还要三次握手啥的。要求的条件也高,既要有IP,还要有端口,差一点就断开重连。由于它保证可靠嘛。在移动互联网状况下,手机的信号或WIFI 不稳定时,都会致使重连。
基于UDP后,能够在QUIC 本身的逻辑里维护链接机制,再也不以IP/Port 做为标识,而是以一个64 位的随机数做为ID 标识,并且UDP 是无链接的,当 IP或Port 变化时,只要ID 不变,就不须要从新链接。
机制二:自定义重传机制
TCP 有序号和应答机制来保证不丢包,一个序号的包发出去没在必定的时间获得应答就会重发。UDP 并无这个机制,QUIC 本身构建了一个机制保证不丢包。
QUIC 也有序列号,是递增的。它也有ACK ,也有重传算法。QUIC 定义了一个offset 概念。QUIC 是面向链接的,是一个数据流,发送的数据在这个流里有个偏移量 offset,能够经过offset 查看数据发送到哪了,这样只要这个offset 的包没有来,就要重发。
机制三:无阻塞的多路复用
同HTTP2.0 同样,同一条QUIC 链接上能够建立多个 stream,来发送多个HTTP 请求。但QUIC 是基于UDP,一个链接上的多个stream之间没有依赖。
机制四:自定义流量控制
TCP 的流量控制是经过滑动窗口协议实现。QUIC 也是经过window_update 控制流量的。可是QUIC 的窗口是适应多路复用机制的。不但在一个链接上有控制窗口,并且在每一个stream 上也有控制窗口。
QUIC 的ACK 是基于 offset 的,每一个offset 的包来了,并进入缓存,就能够应答,应答后就不会重发,中间的空挡会等待到来或者重发便可,而窗口的起始位置为当前收到的最大offset,从这个 offset 到当前的stream 所能容纳的最大缓存,就是真正的窗口大小。这个方法更准确。
小结
HTTP 协议三个部分,状态行、首部、实体,状态行中的get、post、put、delete方法。首部中几个重要字段。
HTTP2.0 经过HTTP 头压缩,多个stream、分帧、二级制编码,多路复用提高性能。