Skip to content

HTTP的实现原理

HTTP是超文本传输协议,也是互联网上使用最广泛的协议之一,较早的(HTTP/2.x之前)版本中使用的是基于TCP进行开发的协议,但目前也有基于UDP拓展的HTTP协议QUIC(HTTP/3.0)。对于2.x和3.x的实现原理我们需要分开说明,因为他们完全是不同的。
要了解HTTP的实现原理,我们需要先了解HTTP协议的定义,HTTP协议的定义可以参考RFC 2616RFC 7230。此外还要了解传输层,以及HTTP工作的原理。

HTTP1.x-2.x和TCP的关系

实际上HTTP(超文本传输协议)和TCP(传输控制协议)是互联网上两种不同的协议,但前者基于后者实现,如果没有TCP则没有HTTP,HTTP位于OSI模型的应用层,而TCP位于传输层。在TCP/IP模型中,HTTP同样位于应用层,而TCP位于互联网层。
因为HTTP依赖于TCP来提供可靠的传输服,所以当客户端和服务器进行HTTP通信时,它们通过TCP连接交换数据。TCP负责建立和维护网络连接,确保数据包的顺序传输,以及检测和修复传输过程中的错误,数据的传输过程都是经过TCP进行传输的,而HTTP则在应用层规范传输协议的数据结构等。
既然HTTP是基于TCP进行传输的,那么在HTTP通信开始之前,客户端和服务器之间必须建立一个TCP连接。这通常涉及到三次握手过程,以确保双方都准备好进行数据传输,一旦TCP连接建立,HTTP请求和响应就可以在这个连接上传输。不过由于最新的QUIC(HTTP/3.x)是基于UDP的,则减少了这个握手的过程。
总而言之HTTP负责将请求和响应封装成消息,TCP则负责连接传输。到了HTTP/3.x则将传输层替换成了UDP,使用UDP进行数据的传输。

HTTP为什么是无状态的

我们都知道HTTP被称为无状态的协议,但是常常有听说它的状态码,有的开发人员刚接触时,会容易混淆这个概念。实际上HTTP请求之所以是无状态的是因为每个请求都是独立的,服务器不会保存任何关于客户端之前请求的状态信息。HTTP响应中的状态码只是对本次请求状态结果的描述,并且每次请求的状态都是独立的。
服务器不会在请求之间保留任何关于客户端的状态信息。这意味着,如果一个客户端发送了多个请求,服务器会把这些请求当作独立的、无关的请求来处理,而通常请求状态信息的持续维护并不是通过协议本身实现的,而是通过对协议的使用,如使用Cookies+Session的方案实现请求状态的管理,这样的方式是在请求的过程中在请求体中传入特定的数据用于标记客户端,服务器根据该数据生成Session文件进行交互而实现状态维护的逻辑。所以每个HTTP请求都是独立的,服务器不会保存任何关于客户端之前请求的状态信息。 而会话的状态,是在请求的基础上,由服务端和客户端进行数据交互而进一步实现的。

HTTP数据的传输过程

HTTP数据的传输过程涉及客户端和服务器之间的多个步骤。在一个典型的请求过程中,HTTP客户端到服务端会经过下面的处理过程,绝大部分都是在客户端和服务端交互中完成如域名的解析等,数据的传输过程在TCP/UCP传输层完成,HTTP主要负责对数据结构的标准化封装,使得客户端到服务端过程中传输的数据结构统一化标准化:

  1. 域名解析(DNS查询)
    • 客户端首先需要将URL中的主机名解析为服务器的IP地址。这通常通过DNS(域名系统)查询来完成。
    • 客户端的操作系统会发送DNS查询请求到本地DNS服务器,然后本地DNS服务器会递归地查询互联网上的DNS服务器,直到找到与主机名对应的IP地址。
  2. 建立TCP连接
    • 一旦客户端获得了服务器的IP地址,它就会尝试与服务器建立TCP连接。
    • 这通常涉及到三次握手过程,客户端发送一个SYN(同步)包到服务器,服务器回应一个SYN-ACK(同步-确认)包,最后客户端发送一个ACK(确认)包,完成连接的建立。
  3. 发送HTTP请求
    • TCP连接建立后,客户端发送一个HTTP请求到服务器。
    • 请求通常包括请求方法(如GET、POST等)、请求的URL路径、HTTP协议版本、请求头(如Host、User-Agent、Accept等),以及可选的请求体(对于POST等请求方法)。
  4. 服务器处理请求
    • 服务器接收到请求后,会根据请求的URL路径和请求方法来处理请求。
    • 这可能涉及到服务器端的业务逻辑处理、数据库查询、文件读取等操作。
  5. 服务器发送HTTP响应
    • 服务器处理完请求后,会发送一个HTTP响应回客户端。
    • 响应包括HTTP协议版本、状态码(如200表示成功,404表示未找到资源等)、状态消息、响应头(如Content-Type、Content-Length等),以及响应体(即服务器返回的资源内容)。
  6. 客户端处理响应
    • 客户端接收到响应后,会根据状态码和响应头来处理响应。
    • 如果是网页内容,客户端(通常是浏览器)会解析HTML,渲染页面,并执行JavaScript代码。
  7. 关闭连接
    • 在HTTP/1.0中,每个请求/响应周期后,TCP连接通常会被关闭。
    • 在HTTP/1.1中,默认使用持久连接(keep-alive),允许多个请求和响应在同一个连接上进行,减少了建立和关闭连接的开销。但最终,连接还是会被关闭,尤其是在一段时间没有数据交换的情况下。
  8. 持久连接和管线化
    • 持久连接允许客户端在同一个TCP连接上发送多个请求,服务器也依次返回多个响应。
    • 管线化(pipelining)是持久连接的一个特性,允许客户端在等待第一个响应的同时发送第二个请求,从而进一步提高效率。 整个HTTP数据的传输过程是由客户端发起的,服务器响应的,并且通常是基于请求/响应模型。随着互联网的发展,HTTP也在不断地进化,例如HTTP/2和HTTP/3等新版本,引入了更多的优化和特性,以支持更高的性能和安全性。

QUIC的传输过程

与HTTP/2.x不同,HTTP/3.0的传输层是UDP。QUIC(Quick UDP Internet Connections)是一种新的传输层协议,由Google开发,旨在提高网络连接的速度和安全性。QUIC基于UDP(用户数据报协议),而不是TCP(传输控制协议),因此它避免了TCP的一些性能瓶颈,并提供了新的特性。不过传输前同样会经过域名解析等,HTTP/3.0是对TCP传输层的覆盖,而协议中的数据结构和HTTP2.x几乎一致,如响应体,请求体,状态码等,下面是对QUIC传输层的大致流程描述:

  1. 连接建立
    • 客户端发送一个初始的QUIC包到服务器,这个包包含了客户端的随机数和可选的加密参数。
    • 服务器接收到这个包后,生成一个密钥对,并将公钥和服务器配置信息发送回客户端。
    • 客户端使用服务器的公钥来加密一个密钥,并将其发送给服务器,这样双方都可以使用这个密钥来加密后续的数据传输。
  2. 握手
    • QUIC的握手过程是集成在初始数据传输中的,这意味着在建立连接的同时就可以开始数据传输,而不需要等待握手完成。
    • 这个过程被称为“零RTT”(Round-Trip Time),因为它减少了建立连接所需的往返次数。
  3. 数据传输
    • 一旦QUIC连接建立,数据就可以在客户端和服务器之间传输。
    • QUIC提供了多路复用,允许在同一连接上同时传输多个数据流。
    • QUIC还提供了流控和拥塞控制机制,以确保数据传输的可靠性和效率。
  4. 拥塞控制和流控
    • QUIC实现了自己的拥塞控制算法,可以在丢包发生时快速调整数据传输速率。
    • 流控机制确保发送方不会超过接收方的处理能力,避免数据溢出。
  5. 前向纠错(Forward Error Correction, FEC)
    • QUIC可以使用前向纠错技术来恢复丢失的数据包,而不需要重传。
    • 这减少了因丢包而导致的延迟,提高了数据传输的效率。
  6. 安全性
    • QUIC内置了TLS(传输层安全性协议)1.3,提供了加密和认证机制,保证了数据传输的安全性。
    • QUIC还提供了对密钥和证书轮换的支持,可以在不中断连接的情况下更新加密参数。
  7. 连接迁移
    • QUIC支持连接迁移,这意味着即使客户端的网络地址发生变化(例如,从Wi-Fi切换到移动数据),QUIC连接也可以保持不变。
    • 这对于移动设备来说是一个重要的特性,因为它可以减少网络切换导致的连接中断。 QUIC的目标是提供一种比TCP更快、更可靠、更安全的传输协议。由于它基于UDP,QUIC避免了TCP的一些问题,如队头阻塞(Head-of-Line Blocking)和缓慢的启动。QUIC的设计考虑了现代网络环境的特点,特别是移动设备和无线网络的普及。随着QUIC的发展,它可能会成为互联网上数据传输的一个重要组成部分。

仅用于培训和测试,通过使用本站代码内容随之而来的风险与本站无关。版权所有,未经授权请勿转载,保留一切权利。
ICP备案号:滇ICP备15009214号-13   公安网备:滇公网安备 53312302000061号