Http的演进
Http在1.1版本之前具有无状态的特点,每次请求都需要通过TCP三次握手四次挥手与服务器重新建立连接。比如某个客户端在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户请求,所以每次需要重新响应请求、耗费不必要的时间和流量。为了节省资源消耗,Http也进行了发展和演进,通过持久连接的方法来进行连接复用。
Http的1.0版本
第一个版本的Http是Http0.9,组成极其简单,只允许客户端发送Get这一种请求,且不支持请求头。由于没有协议头,因此Http0.9协议只支持一种内容,即纯文本。不过网页依然支持用html语言格式化,同时无法插入图片。
http的第二个版本为1.0版本,也是第一个在通信中指定版本号的Http版本,至今依然被广泛采用。相对于Http0.9版本,Http1.0版本增加了如下主要特性:
(1) 请求与响应支持头部字段
(2) 响应对象以一个响应状态行开始。
(3) 响应对象不只限于超文本。
(4) 开始支持客户端通过Post方法向web服务器提交数据,支持GET、Head、Post方法
(5) 支持长连接,但默认使用短连接,缓存机制,以及身份认证。
(6) 请求行必须在尾部添加协议版本字段(Http1.0),必须包含头部消息。
http请求访问的资源不再局限上一个版本的Html格式,可以根据Content-Type设置访问的格式;同时也开始支持Cache。当客户端在规定时间内访问同一URL资源时,直接访问Cache即可。
http请求访问的资源不再局限上一个版本的Html格式,可以根据Content-Type设置访问的格式;同时也开始支持Cache。当客户端在规定时间内访问同一URL资源时,直接访问Cache即可。
MIME类型的每个值包括一级类型和二级类型,之间用斜杠分隔。除了预定义的类型,厂商也可以自定义类型,例如下面是一个自定义类型的例子:
application/vnd.debian.binary-package
上面的自定义MIME类型表明发送的是Debian系统的二进制数据包。
MIME类型值还可以在尾部使用分号、添加参数,下面是一个添加参数的例子:
Content-type: text/html;charset=utf-8
上面的类型值表面Http报文中的报文中的内容是文本网页数据,并且文本编码为utf-8
客户端在发送请求时可以使用Accept头部字段声明自己可以接受哪些数据格式。下面是一个Accept的例子:
Accept: */*
上面的Accept头部字段表明客户端声明自己可以接受来自服务端的任何格式的数据。
由于文本数据发送的时候往往可以通过压缩大大节省带宽,因此Http1.0版本协议可以支持把数据压缩后发送,其报文Content-Encoding头部用于说明数据的压缩格式。
http的1.1版本
Http1.1版本引入了许多关键技术:持久连接、管道机制、分块传输编码、字节范围请求等。
持久连接:即下层的TCP连接默认不关闭,可以被多个请求复用。
管道机制:在同一个tcp连接里允许多个请求同时发送,但是服务器还是按照顺序依次处理。(类似于前端同时发送两个请求给后端)
http1.1新增了put、patch、options、delete等多种请求方法。
http1.1版本客户端请求的头部信息新增了host字段,用来指定服务器的域名,还加了一个新的状态码100.(比如404之类的)
分块传输编码:该机制允许服务端将数据分成多个部分发送到客户端。普通的服务器响应会将响应数据的长度通过Content-Length字段告诉客户端。它主要是用Transfer-Encoding字段
Transfer-Encoding:chunked
每个分块包含十六进制的长度值和数据,其中长度值独占一行。长度不包括分块长度和(\r\n)的长度,也不包括分块数据后面结尾(\r\n)的长度。
最后一个分块的长度值必须为0,对应的分块数据没有内容,表示所有的body数据传输完成。
Http的2.0版本
它是一个二进制协议,传输效率明显提高,但是这样需要客户端和服务端都要引入新的二进制编码和解码的机制。
Protobuf,各位可以去了解一下。
好了,感兴趣的话,可以看看宝宝之前的博客吗0.0
参考文献:java高并发核心编程 Nio、netty、redis、zookeeper 作者:尼恩