应用层相关协议
前言
对于应用层,协议有很多,但比较需要知道的,在我看来就俩个,HTTP和DNS协议,这篇文章就来介绍一下这俩协议叭,特别是HTTP协议,需要特别牢记
应用层
网络服务与最终用户的一个接口。这一层为用户的应用程序提供网络服务
应用层协议:HTTP(超文本传输协议)、DNS(域名解析协议)、SMTP(电子邮件传输协议)、FTP(文件上传协议)
这里就讲一下DNS和HTTP吧,HTTP超级重要!
DNS
什么是DNS
DNS又叫做域名解析协议
域名:
- 域名是一种帮助用户在互联网上寻找路径的为数不多识别码。就比如您的电话号码,您的客户可以通过电话号码联系到你。同样的,您的客户也可以通过域名访问您的企业网站寻找到您。简单来说,域名就是您在网络上的电话号码,例如:
www.baidu.com
就是一个域名,当我们在浏览器输入这个域名后,就可以获取该域名对应的服务器上的资源了 - DNS中的域名都是用句点来分隔的,比如
www.baidu.com
,这里的句点代表了不同层次之间的界限,在域名中,越靠右的位置表示其层级越高
域名又可以被称为URL
- 通常,识别主机的两种方式为:
- 通过主机名,也就是域名(www.baidu.com )
- 通过IP地址
主机名方便人们记忆,IP地址的定长性和层次结构有利于路由识别
- 为了同时满足上述两种需求,我们需要进行主机名到IP地址的转换,也就是将主机名映射为IP地址
DNS则是提供主机名到IP地址的映射服务
- DNS是一个由分层的DNS服务器实现的分布式数据库
分布式层次式数据库
分布式:指DNS服务器分布在全世界
层次式:指DNS服务器是按照层次方式组织的,按层次可以将DNS服务器分为三类- 根DNS服务器
- 顶级域DNS服务器
- 权威DNS服务器
根DNS服务器在最顶层,下一层为顶级域,最后是权威
例如
www.baidu.com
中,com
就是顶级域DNS服务器,baidu
就是权威DNS服务器,www
代表万维网
根域的 DNS 服务器信息保存在互联网中所有的DNS服务器中,这样一来,任何DNS服务器就都可以找到并访问根DNS服务器了 - DNS协议是一个使得主机能够查询分布式数据库的应用层协议
DNS域名解析的工作流程
DNS域名解析有两种方式:
- 迭代查询
- 递归查询
接下来以主机为(Cis.ploy.edu)解析www.baidu.com
获取其IP地址为例迭代查询
- 首先,主机名为(Cis.ploy.edu)的主机向本地DNS服务器发送一个包含了(Cis.ploy.edu)主机名的DNS请求报文
- 本地DNS服务器先查看自己有无对应的映射,如果有就直接返回,没有就执行下面的操作
- 本地DNS服务器将请求报文转发到根DNS服务器
- 根DNS服务器根据域名的最后一位(本例子中为com,还有其他的后缀例如cn,edu等等,这里不多说)向本地DNS服务器返回负责com的顶级域DNS服务器的IP地址列表
- 本地DNS服务器收到回应报文后,就会向顶级域DNS服务器IP地址之一发送查询报文
- 顶级域DNS服务器根据
baidu.com
返回一个权威DNS服务器的IP地址给本地DNS服务器 - 本地DNS服务器根据返回的权威DNS服务器IP地址,发送查询报文
- 权威DNS服务器接收到查询报文后,将
www.baidu.com
的IP地址作为响应发回给本地DNS服务器 - 本地DNS服务器将该映射记录在自己的缓存表后,将该IP地址返回给主机
递归查询
- 首先,主机名为(Cis.ploy.edu)的主机向本地DNS服务器发送一个包含了(Cis.ploy.edu)主机名的DNS请求报文
- 本地DNS服务器先查看自己有无对应的映射,如果有就直接返回,没有就执行下面的操作
- 本地DNS服务器将请求报文转发到根DNS服务器
- 根DNS服务器根据最后一位后缀(com),向对应的顶级域DNS服务器发送查询报文
- 顶级域DNS服务器又向权威DNS服务器发送查询报文
- 权威DNS服务器将查询结果(IP地址)返回给顶级域DNS服务器
- 顶级域DNS服务器将接收到的响应报文转发给根DNS服务器
- 根DNS服务器将收到的响应报文转发给本地DNS服务器
- 本地DNS服务器将该映射记录在自己的缓存表后,将该IP地址返回给主机
其他应用层协议使用DNS的过程
- 同一台用户主机上运行着DNS应用的客户端
- 浏览器从URL(域名)中抽取主机名,将此主机名传送到DNS应用的客户端
- DNS客户端向DNS服务端发送一个包含主机名的请求
- 经过上述的DNS解析过程,DNS客户端接收到一个回答报文,报文中含有主机名对应的IP地址
- 浏览器接收到IP地址后,其向位于IP地址80端口的HTTP服务器,HTTPS的端口为443进程发起一个TCP连接
DNS缓存
指本地DNS服务器将某个服务器返回的响应信息进行缓存。如果本地DNS服务器缓存了一对主机名~IP地址的映射,那么当本地DNS服务器再一次遇到相同的主机名的查询请求时,就可以直接返回对应的IP地址了由于主机名和IP地址的映射不是永久的,DNS服务器在一段时间后将丢弃缓存信息
DNS劫持
DNS劫持就是通过劫持了DNS服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致对该域名的访问由源IP地址转入到修改后的指定IP,其结果就是对特定的网址不能进行访问或者访问的是家的网址,从而实现窃取资料或者破坏原有正常服务器的目的。DNS劫持通过修改DNS服务器上的数据返回给用户一个错误的查询结果来实现的
HTTP
什么是HTTP
HTTP又被叫做超文本传输协议,是一个简单的请求-响应协议,它通常运行在TCP之上(基于TCP/IP协议之上的应用层协议)它指定了客户端(或者服务端)可能发送给服务端什么样的消息以及得到什么样的响应
超文本
先来理解一下什么是
文本:在互联网早期,人们发送的消息还都是文字,但在现在,文本已经从单纯的文字,演变成了可以包含”图片,视频,压缩包等等”,这些在HTTP眼中都是文本
超文本:超文本就是指超出了文本的的文本,听起来有点绕,但其实就是文字,视频,压缩包的混合体,最关键的是超链接,有了超链接,就可以完成从一个超文本跳转到另外一个超文本
HTML就是最常见的超文本,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,在经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了
传输
所谓传输,就相当于把一个东西从一个地方搬到另外一个地方,A搬到B或者B搬到A
在HTTP中,传输的数据就是超文本的,同样的,其传输过程中是允许有中转的,只需要它们都遵守HTTP协议的要求,不打扰基本数据的传输,那么就可以在数据上进行添加其他内容
HTTP是一个双向协议HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」
为什么是两点呢?因为HTTP不光用于客户端-服务端,还应用在服务端-服务端
HTTP的工作原理
HTTP协议定于Web客户端如何从Web服务端请求Web页面,以及Web服务端如何把Web页面传送给客户端
HTTP协议采用了请求/响应模型
客户端向服务器发送一个请求报文,请求报文包含请求的方法,URL,协议版本,请求头部和请求数据
客户端以一个状态行作为响应,响应的内容包括协议的版本,成功或者错误的代码,服务器信息,响应头部和响应数据
HTTP请求报文
请求行:请求行由请求方法,URL,协议版本三个字段组成,每个字段之间用空格隔开,最后面需要有一个换行符
常见的请求方法
- GET:获取资源,可以用来获取URL指定的资源,经过服务器解析后返回响应内容;如果请求的资源是文本,那就原样返回服务器上的文本资源,如果是像CGI(Common Gateway Interface,通用网关接口)那样的程序,则返回经过执行后的输出结果
- POST:传输实体,向指定的URL提交数据进行处理,数据包含在请求体中,其可以导致新资源的创建或者旧资源的更改
- HEAD:获得报文首部,类似于GET,不过返回的不是资源,而是返回响应报文的首部,大多数情况下用来确认URL的有效性以及资源的更新日期等等
- PUT:上传文件,就和FTP协议的文件上传一样,要求在请求报文的请求体中包含文件内容,然后保存到请求URL指定的位置
但鉴于 HTTP/1.1 的 PUT 方法自身不带验证机制,任何人都可以上传文件 , 存在安全性问题,因此一般的Web网站不使用该方法
- DELETE:删除文件,与PUT相反,从请求URL中删除指定的文件
由于HTTP/1.1 的 DELETE 方法本身和 PUT 方法一样不带验证机制,所以一般的Web网站也不使用 DELETE 方法
- OPTIONS:询问支持的方法,查询针对请求URL指定的资源支持的方法
GET和POST都是安全且幂等的嘛
先讲一下什么是安全,什么是幂等
安全:在HTTP协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源
幂等:所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的那么很明显GET方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的
POST因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的
URL:中文名是统一资源定位符
常见的版本号有:HTTP/1.0 HTTP/1.1 HTTP/2.0 HTTP/3.0,后面会介绍它们之间的差别请求头部:请求头部有多个,每个请求头部代表一个要求,并且每个请求头部需要用换行隔开,格式为“属性名:属性值”,服务端据此获取客户端的信息
常见的请求头
- Host:客户端发送请求时,用来指定服务器的域名,有了Host,就可以将请求发给同一台服务器上的不同网站
- Content-Length:客户端发送请求时,这个字段就是表明这次请求的数据长度,就是告诉服务器此次请求包的长度为xxx字节,在xxx字节后的数据是另外一个请求包
- Connection:最常见用于客户端要求服务端使用TCP长连接,以便其他请求复用,
HTTP/1.1
版本的默认连接都是持久连接,但为了兼容老版本的HTTP(HTTP/1.0),需要指定Connection
首部字段的值为Keep-Alive
- Accept:用于客户端向服务器发送请求时,告知服务器自己能够接受什么类型的数据
Accept:*/* 代表客户端可以接收所有类型的数据
- Accept-Encoding:用于客户端向服务端发送请求时,告知服务端自己可以接受哪些压缩方式
Accept-Encoding:gzip 代表客户端可以接受用gzip压缩的数据
一行空行,这个是必须的,请求头部和请求体之间必须有这行
请求体:请求的数据,例如POST的时候,就要将一些数据放入请求体
HTTP响应报文
- 状态行:由协议版本,状态码,状态码描述构成
- 协议版本和请求包里请求行的协议版本一致
- 状态码:它以“清晰明确”的语言告诉客户端本次请求的处理结果
常见状态码
- 1XX:类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少,例如
- 101:协议转变
- 2XX:表示客户端请求成功,是我们最喜欢看到的状态码
- 200:服务器成功返回所有资源,除非请求为HEAD,不然返回的内容都在响应体里
- 204:服务器成功解析请求,但是并没有返回任何资源,也就是说响应体里面没有数据
- 206:服务器成功解析请求,但只返回了一部分资源,应用于HTTP分块下载或断电传输
- 3XX:表示资源的重定向,需要客户端进行一些别的操作才能请求成功
- 301:表示请求的资源永久转移到了另外的服务器上,以后想要访问该资源请更改URL,一般浏览器都会自动转移到目标资源新的服务器上
- 302:表示请求的资源暂时转移到了别的服务器上,需要暂时用另外的URL
301和302都会在响应头里使用字段Location
,指明后续要跳转的URL
,浏览器会自动重定向新的URL
- 4XX:表示客户端发送的请求报文出错,服务端无法解析
- 400:客户端出错,但只是个笼统的错误
- 403:表示服务端的资源禁止访问,这并不是客户端的请求报文出错,也就是服务器拒绝请求
- 404:表示客户端请求的资源不存在或者未找到,无法返回给客户端
- 5XX:表示服务端出错,客户端请求报文没错,但是服务端处理的时候遇到了问题
- 500:服务端出错,但只是个笼统的错误
- 501:表示客户端的请求还不支持
- 502:服务器作为网关出错,表示服务端自身正常,但是访问后端的服务器发送了错误
- 503:服务器现在很忙,暂时无法响应,也就是服务器过载或者服务器在更新
- 504:服务器作为网关,超时了
- 1XX:类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少,例如
- 响应头部:响应报文头,也是由多个属性组成,和请求头部格式一样,只是里面属性内容不同
常见的响应报文头
- Content-Length:服务端在返回数据的时候,会包含
Content-Length
,这个字段就是表明这次回应的数据长度,就是告诉浏览器此次响应包的长度为xxx字节,在xxx字节后的数据是另外一个响应包 - Content-Type:用于服务器回应的时候,告诉客户端,本次数据是什么格式
Content-Type: text/html; charset=utf-8 //告诉客户端,本次数据是网页,并且编码为UTF-8
- Content-Encoding:说明数据压缩的方式。表示服务器返回的数据是用什么压缩格式的,告知客户端需要用这个方式去解压
- Content-Length:服务端在返回数据的时候,会包含
- 一行空行,这个是必须的,和请求报文一样
- 响应正文:响应报文体,即我们真正要的“干货”
HTTP请求和响应的步骤
- 客户端连接到Web服务器:
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接,例如:http://www.baidu.com
- 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文 - 服务器接收请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源副本写到TCP套接字,发送响应报文,由客户端读取。 - 释放连接TCP连接
若Connection模式为Close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;
若Connection模式为Keep-Alive,则该连接会保持一段时间,在该时间内可以继续接收该请求 - 客户端浏览器解析HTML内容
客户端浏览器首先解析响应报文的状态行,查看表明请求是否成功的状态码。然后解析每一个响应头,响应头告知以下若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示在浏览器地址栏键入一个网址后,按下回车键会经历什么
- 浏览器向DNS服务器请求解析该地址的域名所对应的IP地址
- 解析出IP地址后,根据该IP地址和默认端口号80,和服务器建立TCP连接
- 浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP请求,该请求报文作为TCP三次握手的第三次握手报文的数据发给服务端
- 服务端对浏览器请求做出响应,并把对应的HTML文本发送给浏览器
- 释放TCP连接
- 浏览器将该HTML文本显示内容在屏幕上
只能从客户端开始建立连接而开始通信,服务端在没有接收到请求之前不会发送响应,当然这是在HTTP/1.0的情况下
HTTP特性
HTTP最突出的优点就是简单,灵活,易于扩展,应用广泛(跨语言、跨平台),环境成熟
简单
HTTP 基本的报文格式就是header + body
,头部信息也是key-value
简单文本的形式,易于理解,降低了学习和使用的门槛
灵活和易于扩展
- HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充
- 同时
HTTP
由于是工作在应用层(OSI 第七层),则它下层可以随意变化 HTTPS
也就是在HTTP
与TCP
层之间增加了SSL/TLS 安全传输层
,HTTP/3
甚至把TCP
层换成了基于UDP
的QUIC
应用广泛(跨语言、跨平台)
互联网发展至今,HTTP
的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP
的应用片地开花,同时天然具有跨平台的优越性
当然了,HTTP也有缺点,分别是优缺点为一体的无状态和明文传输,以及HTTP最大的缺点不安全
无状态
作为优点:因为服务器没有记忆功能,所以就不需要额外的资源来记录状态信息,不仅实现上会简单一些,而且还能减轻服务器的负担,能把更多的CPU和内存用来对外提供服务
作为缺点:正是因为服务器无记忆功能,他就无法支持需要多个步骤的事务操作,在完成有关联性的操作时会非常麻烦,例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息,这样会使得用户体验极差
解决方案
解决这个问题的方案有很多种,最简单最容易理解的就是Cookie技术
Cookie技术通过在请求和响应报文中的头部写入Cookie信息来控制客户端的状态,简单来说就是:在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了
明文传输
- 作为优点:明文意味着在传输过程中的信息,是可方便阅读的,通过浏览器的 F12 控制台或 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性
- 作为缺点:但是这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔。在传输的漫长的过程中,信息的内容都毫无隐私可言,很容易就能被窃取,如果里面有你的账号密码信息,那你号没了!
不安全
HTTP 比较严重的缺点就是不安全:
- 通信使用明文(不加密),内容可能会被窃听。比如,账号信息容易泄漏,那你号没了
- 不验证通信方的身份,因此有可能遭遇伪装。比如,访问假的淘宝、拼多多,那你钱没了
- 无法证明报文的完整性,所以有可能已遭篡改。比如,网页上植入垃圾广告,视觉污染,眼没了
解决办法:HTTPS
HTTPS
因为HTTP一般是明文传输,很容易被攻击者窃听到重要信息,鉴于此,HTTPS应运而生
- HTTPS与HTTP有很大的不同在于HTTPS是以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份确认保证了传输过程的安全性
- HTTPS在HTTP的基础上增加了SSL层,也就是说
HTTPS=HTTP+SSL
- HTTP默认端口为80,HTTPS默认端口为443
- HTTP建立连接比较简单,只需要TCP三次握手,而HTTPS不光需要TCP三次握手,还需要SSL/TLS的握手后,才能进行加密传输
- HTTPS 协议需要向**CA(证书权威机构)**申请数字证书,来保证服务器的身份是可信的
HTTPS如何保证安全的?
HTTPS通过对称加密和非对称加密以及数字证书来保证安全性
对称加密
即双方用同一种加密算法,生成的是密钥,此时密钥即可以用来加密,也可以用来解密
非对称加密
非对称加密即有两把钥匙,一把公钥,一把私钥,公钥加密的信息只有私钥可以解开,私钥加密的消息也只有公钥可以解开,公钥是公开的,谁都能获取,但是私钥只有自己有,其他人是无法获取的
数字证书
数字证书由CA(证书权威机构)颁发,就是一个包含公钥,身份信息以及数字签名值的一个文件
HTTPS建立连接的过程
我们知道HTTPS=HTTP+SSL,所以一开始还是需要TCP三次握手的,最重要的是后面的SSL/TLS协议
加密流程
- 客户端会先随机生成一个数字A1,然后将A1包含在请求中发送给服务端,该请求中还包括了客户端支持什么加密算法
- 服务端收到请求后,也会随机生成一个数字A2,并且会向CA申请一个数字证书,并将使用非对称加密算法生成的公钥放入数字证书,一起放入的还有随机数A2和根据客户端支持的加密算法之一选择的加密算法
- 客户端接收到服务端传送过来的数字证书后,会对证书进行检查,检查无误后进行下一步
- 客户端生成一个随机数A3,并且用私钥加密,然后用选择的加密算法对随机数A1,A2,A3进行加密,此时生成的是密钥,为非对称加密,将随机数A3发给服务端
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验
为什么要三个随机数
因为这些随机数都是伪随机,当3个伪随机的数字组合在一起,就很接近真随机了
- 服务端用自己的公钥将A3解密出来,随后也就可以用加密算法来加密A1,A2,A3来生成密钥
- 向客户端发生最后的信息:
- 加密通信算法改变通知,表示随后的信息都将用会话密钥加密通信
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验
- 此后,服务端和客户端通信都可以用密钥进行加密
就算黑客拿到了前两个随机数A1,A2,但是没办法获取A3,因为只有服务端有私钥
HTTP的演变
最开始创建的HTTP,也就是HTTP/1.0已经很少用了,大部分都是用HTTP/1.1的,也有的使用HTTP/2.0,或者最新的HTTP/3.0
HTTP/1.0
作为最初始的版本,无疑是存在很多漏洞的,比如上面提到过的明文传输,无状态等等,这些缺点随着时代的发展都慢慢消失了,但除此之外,我们还需要知道HTTP/1.0相对于其他版本的HTTP的不足之处在哪里,这样才能更好地去理解HTTP
HTTP/1.0的缺陷:
- 无连接:HTTP/1.0是无连接、无状态的应用层协议,无状态已经说过了,什么是无连接呢?
无连接
即每次请求都需要建立连接,需要使用Keep-Alive参数建立长连接
无法复用连接,每次发送请求都需要进行TCP连接(三次握手),TCP的连接和释放都是比较费事的,这样频繁连接就会导致网络利用率低 - 队头阻塞:因为HTTP/1.0规定下一个请求必须在之前一个请求响应到达之后才能发送,假设前一个请求一直没有被响应,那么接下来的请求就都会被阻塞
为了解决这些问题,HTTP/1.1就出世了
HTTP/1.1
- 相比于HTTP/1.0,HTTP1.1提出了长连接的通信方式,也叫做持久连接,这种方式的好处就是减少了TCP创建和销毁的所造成的额外开销,减轻了服务端的负载压力,其特点就是:
只要有一方没有明确提出断开连接的要求,就会一直连接下去
- HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能
即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间
举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求
,然后等待服务器做出回应,收到后再发出B请求
。管道机制则是允许浏览器同时发出A请求
和B请求
,但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是 前面的回应特别慢,后面就会有许多请求排队等着。也就是说并没有解决掉队头阻塞的问题
但这还是会出现队头阻塞的问题,因为当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据
同样的,HTTP/1.1在性能上还是不足的,原因如下:
请求/响应头部(Header)
未经压缩就发送,首部信息越多延迟越大,只能压缩Body的部分- 发送冗长的首部,每次互相发送相同的首部造成的浪费较多
- 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞
- 没有请求优先级控制
- 请求只能从客户端开始,服务器只能被动响应
HTTP/2.0
HTTP/2.0是基于HTTPS的,所以HTTP/2.0就解决了HTTP不安全的问题
头部压缩
HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的分
这就是所谓的HPACK算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了
二进制格式
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式
头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧
这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率
数据流
- HTTP/2.0的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应
- 每个请求或回应的所有数据包,称为一个数据流(Stream)
- 每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数,服务器发出的数据流编号为偶数
- 客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求
多路复用
HTTP/2.0是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应移除了 HTTP/1.1 中的串行请求
,不需要排队等待,也就不会再出现队头阻塞问题,降低了延迟,大幅度提高了连接的利用率
举例来说,在一个 TCP 连接里,服务器收到了客户端A和B的两个请求,如果发现A处理过程非常耗时,于是就回应A请求已经处理好的部分,接着回应B请求,完成后,再回应A请求剩下的部分
服务器推送
HTTP/2 还在一定程度上改善了传统的请求 - 应答工作模式,服务不再是被动地响应,也可以主动向客户端发送消息
举例来说,在浏览器刚请求HTML的时候,就提前把可能会用到的JS、CSS文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)
HTTP/2.0也还是有问题的,因为是多路复用的缘故,多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的
所以一旦发生丢包现象,就会触发TCP的超时重传(后面会专门写一篇文章关于TCP的)机制,这样在一个TCP连接中的所有HTTP请求就必须等待丢失的包重传
- HTTP/1.1 中的管道( pipeline)传输中如果有一个请求阻塞了,那么队列后请求也统统被阻塞住了
- HTTP/2 多请求复用一个TCP连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求
这些都是TCP传输层的问题,所以HTTP/3.0就在TCP传输层上作了改动
HTTP/3.0
HTTP/3.0把HTTP下层的TCP协议该成了UDP
UDP 发生是不管顺序,也不管丢包的,所以不会出现 HTTP/1.1 的队头阻塞 和 HTTP/2 的一个丢包全部重传问题
大家都知道 UDP 是不可靠传输的(为什么是不可靠,后面会和TCP一块将),但基于UDP的QUIC协议可以实现类似TCP的可靠性传输
QUIC有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响
TL3升级成了最新的1.3版本,头部压缩算法也升级成了QPack
HTTPS要建立一个连接,要花费6次交互,先是建立三次握手,然后是TLS/1.3的三次握手
QUIC 直接把以往的TCP和TLS/1.3的6次交互合并成了3次,减少了交互次数
所以,QUIC是一个在UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议QUIC是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以HTTP/3现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭TCP
结语
HTTP的知识点还是蛮多的,而且还是面试官很喜欢问的,所以是有必要牢牢掌握的,关于HTTPS的数字证书这一块后面会进行补充的,我感觉我写的不是很完整,我后面再写吧,今天就先到这里吧
- 标题: 应用层相关协议
- 作者: 这题超纲了
- 创建于: 2023-03-16 13:46:40
- 更新于: 2023-06-23 14:42:56
- 链接: https://qx-gg.github.io/2023/03/16/blog13/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。