1. HTTP协议
首先HTTP协议是一个简单的请求-响应协议, 也叫作超文本传输协议, 在早期专门用于传输超文本数据html, 但是随着协议发展多元化, 开始不限制传输格式. 在TCP/IP协议栈当中, 它是运行在应用层上的协议. 它指定了客户端可能发送给服务器什么样的消息以及得到什么样的相应.
注意: 这里我们要注意的是应用层是直面我们程序员的一层, 因为应用程序使我们程序员自己写的, 因此应用层的通信协议可以有我们自己来制定, 而HTTP就是一种知名的应用层通信协议.
2. 关于HTTP的发展历程(HTTP的协议版本)
HTTP的发展目前经历了四个版本阶段:
-0.9版本: 处于这个阶段的HTTP协议只是一个简单的交换信息的无序协议, 并且数据的传输仅仅是文字, 这个时候还没有形成固定完整的协议格式, 请求方法只有get
-1.0版本: 1.0版本当中正式规定了HTTP协议的协议格式, 并且增加了多种请求方法, 支持不同文件格式的数据流.
-1.1版本: 在1.0版本的基础上增加了更多的请求方法以及头信息, 这个时候更加注重传输性能以及效率的提升. 并且这个时候开始支持长连接以及管线化传输.
-2.0版本: 2.0版本开始采用二进制流传输, 并且进行多路复用, 并且允许服务端主动向客户端推送数据.
3. HTTP协议格式
HTTP报文由从客户端到服务端的请求 和 从服务端到客户端的相应组成;
请求报文的格式如下:
首行: 首行也叫作请求行, 会包含本次请求的请求方法, URL, 协议版本信息等
头部: 描述本次请求的关键字段信息, 由key:val形式的键值对组成, 并且每个键值对以\r\n作为结尾 ----- key:val\r\nkey:val\r\n
其中一些请求的关键字段信息一般有:
Connection-控制长连接/短连接
Cache-Control-缓存控制
User-Agent-客户端的属性
Accept-描述自己所能接收数据的属性
Content-Length-描述正文长度
Content-Type-描述正文的数据类型
…
空行: 空行主要是为了间隔头部与正文
接收HTTP数据的时候, 当连续接收两个\r\n的时候, 认为头部到此结束(即\r\n\r\n)
正文: 正文则是提交给服务端的数据
响应报文的格式如下:
首行: 也叫作状态行, 能够表示请求处理结果的状态, 首行包含三个要素, 以空格进行间隔, 包含协议版本, 响应状态码, 状态描述, 以\r\n作为结束.
例如: HTTP/1.1 303 See Other
头部: 关于本次响应的一些关键字段描述信息, 以key:val键值对组成, 以\r\n作为结尾
其中一些相应的关键字段信息一般有:
Transfer-Encoding: 实体正文的传输方式
Expires: 缓存过期的时间
Location: 重定向的新位置
Set-Cookie: 服务端通过set-cookie向客户端传递信息, 会被保存在客户端浏览器的cookie文件当中
Cookie: 客户端每次通信从cookie文件当中读取数据, 通过cookie向服务端传递信息
cookie的使用并不安全, 因此需要搭配Session使用
Session: 会话, 服务端会为每个登陆的客户端创建一个会话, 在服务端描述一些会话信息(客户端身份信息, 状态信息), 将其保存在服务端, 可以通过cookie将session id返回给客户端, 客户端每次通信都会通过cookie带有自己的session id.
cookie和session的区别
** cookie持续传递客户端信息状态的字段, cookie是保存在客户端上的数据, 用于持续与服务端进行信息传递的一种手段**
session是一种会话的控制, 服务端保存的会话信息包含客户端的身份状态信息
空行: 空行主要是为了间隔头部与正文
接收HTTP数据的时候, 当连续接收两个\r\n的时候, 认为头部到此结束(即\r\n\r\n)
正文: 服务端响应的实体资源
4. HTTP的通信过程
由于HTTP协议是在传输层基于TCP通信实现, 因此HTTP也是基于C/S模式的(客户端/服务端模式), 并且是面向连接的.
典型的HTTP通信过程
-搭建TCP客户端以及服务端程序, 并且建立连接
-客户端组织HTTP协议格式请求数据/资源, 向服务器发出请求
等待服务器的响应
-服务器收到客户端的请求, 按照规定的HTTP协议格式对请求进行解析, 并根据请求组织响应信息以及对应的实体资源
-服务端业务处理结束之后, 按照HTTP协议格式组织信息和数据对客户端进行响应
5. 关于HTTP协议当中的Connection头部字段
在HTTP通信当中, 长短连接的控制是通过通用头部字段Connection字段完成的.
Connection: keep-alive
Connection: close
Connection一般用于控制网络连接是否保持打开状态, 当前事务结束之后, 如果发送的值是keep-alive, 则说明连接是持久的并且不关闭, 从而允许客户端对同一服务器的后续请求完成
close 表示客户端或服务器想要关闭连接. 这是HTTP/1.0请求的默认值
keep-alive 表示客户端想要保持连接处于半打开状态. 持久连接是 HTTP/1.1请求的默认值
短连接: HTTP基于传输层tcp实现通信, 每一次通信都对应一次TCP连接的建立, 完成请求/响应的过程, 通信完毕后断开连接.
但是, 在HTTP/1.0版本当中, 并没有过多的考虑互联网中最重要的速度和效率, 也正因为如此, 在HTTP/1.1当中引入了管线化长连接的思想. 实现管线化长连接传输的目的是为了每一次建立连接, 能够完成多个请求的通信, 也就是说可以在建立连接之后一次性发送多个请求, 服务器在收到请求之后也可按照客户端的请求顺序依次进行响应, 通过这种方式减少连接建立以及断开的次数, 这样能够大大避免TCP拥塞机制所造成的传输效率降低问题.
这就引出了长连接的思想.
长连接: 在一次通信当中, 建立一个连接, 可以连续发送多次请求, 服务端按序进行响应进而减少连接建立以及断开的次数.
知道了如上长短连接的思想, 接下来我们需要注意的是, 在HTTP/1.1中的管线化长连接虽然在一定程度上提高了传输效率, 但是仍然存在着队头阻塞的问题, 因为服务端是按请求顺序进行组织响应的(如果第一条请求处理比较慢, 会影响其他的响应无法及时到达客户端, 必须要等待请求1的处理完成), 而这个问题在HTTP/2.0中得到了解决.