http协议初解

本文最后更新于:9 个月前

http概述

  超文本传输协议HTTP是分布式、协作的、超媒体信息系统的应用层协议。它是通用的,无状态的协议,可以用在超文本用途之外的许多任务,如名称服务器和分布式目标管理系统,通过扩展它的请求方法,错误码和头部。HTTP的一个特性是数据表示的引入和协商,允许系统建立独立的传输数据。
  我们就这个名字超文本传输协议进行分析,可以解构为超文本传输协议

  1. 超文本
    什么是超文本?超越文本的内容就是超文本,早期的计算机是以文字进行传输的,后来的极速发展导致更多形式的数据可以进行传输,图像视频音频等,所以这些“文本”就被称为超文本
  2. 传输
    我们要进行终端与终端间的传输,我们需要把文本转成二进制通过物理链路进行传输,其中双方还需要对传输进行响应,才能达到传输的目的
    传输模型
  3. 协议
    计算机之间通信需要互相遵循的规则,就是网络协议。http协议就是一种计算机之间通信的的规范和约束。

    计算机网络协议模型

    OSI七层模型

      ISO(国际标准化组织)提出来计算机网络应该按照7层来组织,于是诞生了OSI七层模型。
    七层模型
    我们从上往下看这七层模型都发挥了什么作用:
  • 应用层
    特定网络应用协议存放的一层,为我们特定的网络应用提供服务我们平时的超文本传输协议HTTP,电子邮件传输的SMTP,文件传输的FTP,域名解析的DNS等等。
  • 表示层
    主要对数据的操作,对数据进行加密、压缩或者描述,负责把下一层传来的数据转换成应用层能够使用的数据形式,把应用层的数据转换成适合网络传输的格式。
  • 会话层
    为不同机器间创建和管理会话的一层
  • 传输层
    传输层是承上启下的一层,下三层主要是进行数据的传输,上三层主要进行数据的处理,传输层主要就是建立正确的端到端的通信,确保保文的正确传输,该层主要有两种协议,分别是可靠传输TCP和不可靠的UDP
    • TCP:一种面向连接的、可靠的、基于字节流的传输层通信协议(TCP,Transmission Control Protocol),建立通信前会先建立一个TCP连接,类似于打电话中的“喂,你是xxx吗”,回答“我是xxx”,通过三次握手建立稳定的连接,在结束连接是会进行四次挥手断开连接。
        在TCP协议中会通过对数据进行检验确保数据的正确性和合法性,通过超时重传的方式保证连接的可靠性,通过用拥塞控制算法(AIMD算法)实现对网络传输的控制,通过滑动窗口的方式达到流量控制的目的。
    • UDP:一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的IP数据包的方法.
        由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。正是因为UDP在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作。也正是因此,UDP具有较好的实时性,工作效率较TCP协议高;而且因为UDP段结构比TCP的段结构简单,因此网络开销也小。很适合分发信息的操作,哪怕信息错误,很快就会被新的信息替代,平时的实时视频音频大多会使用UDP。
  • 网络层
    负责在网络中找到合适的路径抵达我们的目标网络,通过路由算法和寻址等方法建立起合适的路径。
  • 链路层
    数据链路层就是实现物理信号和数据帧转化,接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传输。
  • 物理层
    物理层的主要功能就是利用传输介质(例如:网线,无线电波,光)为数据链路层提供物理连接,实现比特流的透明传输。
      以上,建立在该网络模型之上,HTTP可以实现两点之间文字视频等超文本数据的传输。

    TCP/IP 四层模型

      在TCP/IP中会话层和表示层被放在了应用层中,其他层主要内容是一样的。
    TCP四层
      其上的两层分别是以下内容,其他层作用一样。
  • 应用层
    主要有负责web浏览器的HTTP协议, 文件传输的FTP协议,负责电子邮件的SMTP协议,负责域名系统的DNS等。
  • 传输层
    主要是有可靠传输的TCP协议,特别高效的UDP协议。主要负责传输应用层的数据包。

HTTP工作流程


一次HTTP操作称为一次事务,可以分为四步:
1、首先客户和服务器需要建立连接,用户点击一个链接或者发出一次请求,HTTP请求开始工作
2、建立连接成功后,客户发送一个HTTP请求给服务器

  • HTTP请求组成:请求行、消息报头、请求正文,
  • 请求的内容是以一个方法符号开头,后面跟着请求的URL、协议版本号、客户信息等别的可能的内容


3、服务器收到请求后,给予相应的响应信息

  • HTTP响应组成:状态行、消息报头、响应正文。
  • 内容包括:服务器HTTP协议的版本,服务器发回的响应状态代码和状态代码的文本描述、服务器信息等别的可能的内容

4、客户端收到服务器返回的信息通过浏览器显示在用户的显示屏上,确定没问题后断开连接

其中HTTP请求后返回的状态码不同的开头数字分别代表了不同的意义

HTTP状态码

所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。状态代码的第一个数字代表当前响应的类型:

状态码 类别 意义
1xx 消息 请求已被服务器接收,继续处理
2xx 成功 请求已成功被服务器接收、理解、并接受
3xx 重定向 需要后续操作才能完成这一请求
4xx 请求错误 请求含有词法错误或者无法被执行
5xx 服务器错误 服务器在处理某个正确请求时发生错误

虽然RFC 2616中已经推荐了描述状态的短语,例如200 OK404 Not Found,但是WEB开发者仍然能够自行决定采用何种短语,用以显示本地化的状态描述或者自定义信息。
  关于状态码,有些有意思的图解,虽然有些味道,但是描述的还挺形象的。

TCP的三次握手和四次挥手

TCP的建立连接断开连接是通过三次握手四次挥手实现的,要理解这种连接方式,我们需要先知道TCP报头的组成方式,如下如所示:

其中比较重要的就是序号、确认号和标识位:

  1. 序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  2. 确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。(千万不要与标志位中的ACK搞混,这两个不是一个东西)
  3. 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
    • URG:紧急指针(urgent pointer)有效。
    • ACK:确认序号是否有效,一般置为1。
    • PSH:提示接收端应用程序立即从 TCP 缓冲区把数据读走。接收方应该尽快将这个报文交给应用层。
    • RST:重置连接。对方要求重新建立连接,复位。
    • SYN:请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为 1
    • FIN:释放一个连接。

  三次握手四次挥手流程

  我们详细解读一下这个图的流程:

  1. 第一次握手:
    首先,客户端发出请求,请求的标志符SYN为1,随意生成一个seq序号,告诉服务器“我想建立连接”,此时客户端进入SYN_SENT已发送阶段
  2. 第二次握手:
    服务器收到请求后,从LISTEN状态转成SYN_RCVO已收到阶段,然后发回请求,请求的标志符SYN为1,ACK为客户端的seq序号+1,确认是否之前的请求有效,随意生成的一个seq序号,告诉客户端“我同意连接,你准备好连接了吗”
  3. 第三次握手:
    客户端收到服务器确认后,进入ESTABLISHED已连接状态,然后发回请求,标志符ACK为服务器的seq序号+1,告诉服务器“我准备好连接了”,服务器收到后也进入ESTABLISHED已连接状态
  4. 自此正式建立连接,进行正常的数据交互
  5. 第一次挥手:
    结束数据交互后,要结束连接,此时客户端发送FIN告诉服务器“我要结束连接了”,并进入FIN-WAIT-1终止等待1状态
  6. 第二次挥手:
    • 服务器收到请求后,立刻发出ACK标志的确认请求,告诉客户端“我知道了”,此时客户端进入FIN-WAIT-2终止等待2状态,等待服务器发出连接释放的请求。
    • 随后服务器进入CLOSEWAIT(关闭等待)状态,TCP进程去询问应用层是否没有数据要传输了,此刻如果有数据那么依旧会进行数据传输,客户端也会接收,
  7. 第三次挥手:
    当服务器知道没有数据要发送时,发送FIN报文,告知客户端“要断开连接了”,此时服务器进入LAST-ACK最后确认状态
  8. 第四次挥手:
    客户端收到报文后,立刻发出确认报文,告知“已知晓”,然后进入TIME_WAIT时间等待状态,在结束时间等待后才会彻底释放TCP连接,至此整个TCP连接完成。

HTTP的优劣

言归正传,我们来看看HTTP协议的优点和缺点:

优势

HTTP的优势很明显,如下几个是比较突出的:

  1. 简单灵活易扩展
    因为HTTP的只规定了基本格式,空格分隔单词,换行分隔字段等。其他地方部分都可以由开发者自由定义,所以特别的灵活易扩展
  2. 可靠传输
    因为使用了TCP/IP,所以继承了TCP,具备可靠传输的特性。
  3. 无状态
    因为服务器不需要记忆这些状态,所以既能减轻服务器负担又能简化请求。

缺点

同时HTTP也有一下缺点:

  1. 无状态
    因为无状态,所以无法处理连续事务,不过服务端也发展出了Cookie来进行记录。
  2. 明文传输
    因为HTTP的明文传输,所以很容易被人截获具体内容,非常不安全。
  3. 队头阻塞
    因为HTTP的采用了TCP协议,所以一旦某个连接很长,那么会导致其他连接被阻塞。

HTTP各版本的区别

HTTP 0.9

  HTTP0.9的主要内容
  1991年,原型版本,功能简陋,只有一个命令GET,只支持纯文本内容,该版本已过时。

HTTP 1.0

  HTTP1.0的主要内容

  • 任何格式的内容都可以发送,这使得互联网不仅可以传输文字,还能传输图像、视频、二进制等文件。
  • 除了GET命令,还引入了POST命令和HEAD命令。
  • http请求和回应的格式改变,除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。只使用 header 中的 If-Modified-SinceExpires 作为缓存失效的标准。
  • 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
  • 通常每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名

    HTTP 1.1

    HTTP1.1的主要内容
  • http1.1是目前最为主流的http协议版本,从1999年发布至今,仍是主流的http协议版本。
  • 引入了持久连接( persistent connection),即TCP连接默认不关闭,可以被多个请求复用,默认是Connection: keep-alive,即开启,设置Connection: close手动关闭。配合Keep-Alive: timeout=5, max=1000来设定连接时长。其中timeout指定一个空闲连接需要保持打开状态而最小时长(单位:秒)。max指定此次连接的最大请求数。
  • 引入了管道机制( pipelining),即在同一个TCP连接里,客户端可以同时发送多个请求,进一步改进了HTTP协议的效率,会造成队头阻塞。
  • HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match,If-None-Match 等缓存控制标头来控制缓存失效。
  • 支持断点续传,通过使用请求头中的 Range 来实现。
  • 使用了虚拟网络,因为在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。所以HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。
  • 新增方法:PUT、 PATCH、 OPTIONS、 DELETE。

HTTP1.*的主要问题

  1. 因为持久连接的缘故,如果某些文件频繁的被请求,那么keep-alive导致了文件被请求之后还保持了不必要的连接很长时间,这会使得使得服务器性能下降。
  2. 因为管道的机制,所以所有的通信都是在管道内按序进行的,一旦某个连接持续时间过久,会导致整体任务被阻塞,这就是队头阻塞。
      

    HTTP 2.0

  • 二进制分帧
    这是一次彻底的二进制协议,以二进制代替原本的明文传输,头信息和数据体都是二进制,并且统称为”帧”:头信息帧和数据帧。
  • 头部压缩
    HTTP 1.1版本会出现 「User-Agent、Cookie、Accept、Server、Range」 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法进行压缩。
  • 多路复用
    复用TCP连接,不断的发帧,每帧的stream identifier都标明这一帧属于哪个流,然后在对方接收时,根据stream identifier拼接每个流的所有帧组成一整块数据。把HTTP/1.1 每个请求都当作一个流,那么多个请求变成多个流,请求响应分成多个帧,这样都个连接可以在一个连接里实现数据交换,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,这样子解决了队头阻塞的问题、减少了TCP连接数,同时解决的TCP慢启动的问题。
  • 服务器推送
    允许服务器未经请求,主动向客户端发送资源,即服务器推送。
    • 客户端可以缓存推送的资源
    • 客户端可以拒收推送过来的资源
    • 推送资源可以由不同页面共享
    • 服务器可以按照优先级推送资源
  • 请求优先级
    可以设置数据帧的优先级,让服务端先处理重要资源,优化用户体验。

综上,大致是HTTP的各个版本的一些特点和TCP的连接形式,在HTTP上还有一个HTTPS,虽然他只是在HTTP上套了一层加密,涉及了密码学、TLS/SSL,所以其中的门道也不少,可惜这里地方太小写不下了。

参考:
[1]https://juejin.cn/post/6857287743966281736#heading-27
[2]https://juejin.cn/post/6844903667569541133#heading-35


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!