首页 关于 微信公众号
欢迎关注我的微信公众号

HTTP协议

简介

HTTP(Hyper Text Transfer Protocol-超文本传输协议),是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。

超文本传输 ​​ 协议(HTTP)是用于传输诸如 HTML 的超媒体文档的应用层协议。它被设计用于 Web 浏览器和 Web 服务器之间的通信,但它也可以用于其他目的。HTTP 是一个基于 TCP/IP 通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。也要通过三次握手,四次挥手。

HTTP/0.9

HTTP/0.9也叫做单行协议。该版本的协议及其简单,只有一个当行命令。包括GET方法和请求路径。响应是一个HTML文档,没有头部和其它元数据。只有HTML,其默认使用的是80端口。

[root@VM_0_5_centos ~]# telnet www.sina.com.cn 80
Trying 111.10.42.194...
Connected to www.sina.com.cn.
Escape character is '^]'.
GET /
<HTML>
<HEAD>
<TITLE>Not Found on Accelerator</TITLE>
</HEAD>

<BODY BGCOLOR="white" FGCOLOR="black">
<H1>Not Found on Accelerator</H1>
<HR>

<FONT FACE="Helvetica,Arial"><B>
Description: Your request on the specified host was not found.
Check the location and try again.
</B></FONT>
<HR>
</BODY>
Connection closed by foreign host.

上面演示了使用HTTP请求的GET /请求新浪服务器的根文件。

HTTP/0.9具有如下特点:

HTTP/1.0

随着WEB越来越流行,HTTP/0.9功能性不足暴露出来。大家需要一种协议不仅能够传输HTML,还能传输其它文档。可以给请求和响应提供元数据。于是1996年HTTP工作组发布 RFC 1945。不过RFC只是参考性的。HTTP/1.0并不是一个正式规范。

报文示例:

GET /mypage.html HTTP/1.0
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)

HTTP/1.0 200 OK
Content-Type:text/html
Content-Length:1024

HTTP/1.0新增特性:

注意:服务器和客户端的连接在每次请求完成之后关闭,这一点跟HTTP/0.9一样。

HTTP/1.1

1997年1月,距离HTTP/1.0发布半年之后,HTTP/1.1正式发布(RFC 2068),两年半之后,HTTP/1.1进行了一次大改进(功能增强,性能改进),标志着HTTP/1.1进入了成熟阶段。

HTTP/1.1报文示例:

GET /mypage.html HTTP/1.1
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)

HTTP/1.1 200 OK
Content-Type:text/html
Content-Length:1024
Connection:keep-alive
Transfer-Encoding:chunked

100
<!doctype html>
……
100
……
0

GET /favicon.ico HTTP/1.1
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Connection:clouse

HTTP/1.1 200 OK
Content-Type:image/x-icon
Content-Length:3638
Etag:W/sdfsd-xxxx

……(图片数据)
Connection closed by foreign host.

HTTP/1.1主要新增功能:

持久连接

HTTP/1.0 每进行一次 HTTP 通信,都需要经历建立 TCP 连接、传输 HTTP 数据和断开 TCP 连接三个阶段。

在当时,由于通信的文件比较小,而且每个页面的引用也不多,所以这种传输形式没什么大问题。但是随着浏览器普及,单个页面中的图片文件越来越多,有时候一个页面可能包含了几百个外部引用的资源文件,如果在下载每个文件的时候,都需要经历建立 TCP 连接、传输数据和断开连接这样的步骤,无疑会增加大量无谓的开销。 为了解决这个问题,HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。

HTTP 的持久连接可以有效减少 TCP 建立连接和断开连接的次数,这样的好处是减少了服务器额外的负担,并提升整体 HTTP 的请求时间。

持久连接在 HTTP/1.1 中是默认开启的,所以你不需要专门为了持久连接去 HTTP 请求头设置信息,如果你不想要采用持久连接,可以在 HTTP 请求头中加上 Connection: close 。不同浏览器对同一域名所支持的最大连接数不同(网上大多都说默认是6个,但是没找到十分确切的数据。 参考连接 https://yq.aliyun.com/articles/611340 , https://blog.csdn.net/wenshu12321/article/details/69488029)。

分块传输编码

分块传输编码(Chunked transfer encodiing)超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。

通常,HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。通常数据块的大小是一致的,但也不总是这种情况。

HTTP 1.1引入分块传输编码提供了以下几点好处:

如果一个HTTP消息(请求消息或应答消息)的Transfer-Encoding消息头的值为chunked,那么,消息体由数量未定的块组成,并以最后一个大小为0的块为结束。

增强缓存控制

具体可参考 https://www.cnblogs.com/Iwillknow/p/3957183.html

HTTP管线化(不成熟)

持久连接虽然能减少 TCP 的建立和断开次数,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果 TCP 通道中的某个请求因为某些原因没有及时返回,那么就会阻塞后面的所有请求,这就是著名的队头阻塞的问题。

HTTP/1.1 中试图通过管线化的技术来解决队头阻塞的问题。HTTP/1.1 中的管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求,依然会产生队头阻塞(head of line blocking)因此该特性在浏览器默认均不开启,为了实现HTTP请求并发,浏览器大都为每个域名开多个TCP连接。

http/1.0http/1.1中的 Head of line blocking、Multiplexing图释:

HTTP/2.0

HTTP/2.0主要是为了解决HTTP/1.1的性能问题(TCP连接不能多路复用),为了达到这个目的,HTTP/2.0增加了二进制分帧层,保留之前的使用方式不变,功能略有增加。

HTTP/2.0特性

借助二进制分帧层实现多路复用

HTTP/2.0的性能增强核心,几乎全在二进制分帧层。如下图所示:

HTTP/2.0中,TCP连接是以流的方式建立的,如下图所示。

借助二进制分帧层,给每一次交互分配一个流ID,客户端和服务端吧请求和响应分割为一系列的帧,附上流ID,多个流的帧可以交替发送,到另一端再按顺序重新组合。从而实现发送请求和响应时多路复用底层TCP连接,多个请求被分配了多个流ID,不会互相干扰。浏览器只需要给每一个源分配一个连接,大大减少TCP慢启动的影响以及底层连接之间的竞争;同时节省服务端和客户端内存文件描述符资源,简化浏览器对底层连接的管理。

HTTP2.0帧结构

以下是HTTP/2.0中的常见概念:

以下是HTTP/2.0中的帧结构:

HTTP/3.0

HTTP/2.0作为一个应用层协议,基本已经无可挑剔,然而目前HTTP/2.0底层依然使用TCP协议作为传输层,由于TCP协议是一个可靠的传输协议,需要把网络分组按序完整的交给应用层,当某一分组丢失时,TCP就会等待发送端重传,已到达分组的暂时放到接受缓存队列中,收到重传后再一起交给应用层。这种情形叫队首阻塞。如果队列中有各个流的分组,则其中一个流的分组丢失会阻塞其他流的数据,导致应用层不能接受。如下图,由于stream2丢失了一个分组,导致stream3和stream4的分组即便都到了接收端,依然不能交给应用层读取。这样HTTP 2.0费尽⼼思设计的二进制分帧层以隔离个流/请求之间的相互影响,由于TCP队首阻塞的存在,还是没有办法真正实现流之间相互不阻塞。

为了彻底解决这个问题,HTTP2.0 over QUIC应运而生。然而QUIC和TCP之间有何区别呢,且看下图,QUIC协议是基于UDP实现的一个可靠的传输层协议,它的拥塞控制比起TCP粒度更细,⼀个QUIC连接里面可以设置很多个流(借鉴HTTP2.0),每个流有自己的拥塞控制和流量控制,这样即使stream2中有一个分组丢失了,只会阻塞在stream2的接收队列,stream3和stream4分组到达后可以立即交给应用层读取,不受stream2影响。2018年年10月,HTTP 2.0 over QUIC已被重新命名为HTTP 3.0

参考

Blog

Opinion

Project