一次HTTP请求的完整过程分析

最近在复习HTTP协议、TCP/IP协议的相关知识。为了理清这些协议的关系和一些要点,本文以“一次HTTP请求的完整过程”为例,对此进行分析。水平有限,若有不当之处,还望指正。

一次HTTP请求的完整过程应该包括以下的一些步骤:

  • 服务器在指定IP和端口上监听请求连接;
    • 监听套接字
  • 客户端发起请求和服务器建立连接;
    • DNS域名解析确定服务器IP地址;
    • 客户端建立请求套接字和服务器监听套接字连接(逻辑上);
    • 客户端沿着物理线路和服务器的“三次握手”(物理上)
      • 沿着物理路线传输数据包
        • 应用层传递报文给下一层;
        • 运输层将报文分组为报文段,添加首部,实现端对端交付、流量控制和差错控制;
        • 网络层将分组添加IP首部,进行逻辑编址,负责将分组从一个网络传递到另一网络,实现网络互联
        • 数据链路层将分组组装成帧,添加首部和尾部,进行物理编址,为物理层提供可靠的链路;
        • 物理层将比特流进行编码并在物理介质终传输数据
      • “三次握手”(组装数据包和传输数据包的过程)
        • 客户端 -> 服务器:SYN
        • 服务器 -> 客户端:SYN + ACK
        • 客户端 -> 服务器:ACK
  • 客户端发起HTTP请求;
    • 生成请求报文
    • 发送请求报文到服务器
  • 服务器处理请求,并返回数据给客户端;
    • 接收请求报文
    • 解析请求报文
    • 处理请求
    • 发送相应报文
  • 客户端和服务器断开连接
    • 客户端 -> 服务器:FIN
    • 服务器 -> 客户端:ACK
    • 服务器 -> 客户端:FIN
    • 客户端 -> 服务器:ACK

由于HTTP请求和响应的过程中不可避免地涉及到数据在网络系统中的通信。因此,我们首先对数据在网络系统中的通信过程进行分析,之后在对HTTP请求和响应的具体过程进行探讨。

数据在网络系统中的通信

数据在网络系统中的通信涉及到OSI模型与TCP/IP协议族。OSI模型是一个分层的框架结构,其目的是为了设计出能够让各种类型的计算机系统相互通信的网络系统,它将网络系统设计为七层,分别为:物理层、数据链路层、网络层、运输层、会话层、表现层、应用层。而TCP/IP协议族中将整个网络系统划分为五层,前四层类似于OSI模型,只是将后三层统一划分到应用层,故只有物理层、数据链路层、网络层、运输层和应用层。以下部分以TCP/IP协议族中的五层模型为例进行说明数据在网络系统中的通信过程。以下是TCP/IP协议和OSI模型的比较图

TCP/IP协议和OSI模型的比较图
来源:《TCP/IP协议族 (第4版)》

首先,应用层 能够让用户获得网络所提供的服务,这一层上定义了许多的协议,例如万维网、电子邮件、文件传送等服务。在这一层上用户可以发送数据报文,经过运输层、网络层、数据链路层对数据报文的包装,最后通过物理层的传输将其传送到目标用户。

第二,运输层 能够将应用层的数据报文完整地从源地址交付给目标地址。运输层可能会将数据报文分组为报文段,并为其添加首部,包括源端口、目标端口等信息。首部一方面是为了保证端对端(不仅是确定目标计算机,还要确定是计算机上的哪个程序)的数据交付,另一方面也实现了数据交付过程中的差错控制(例如解决数据失序到达或者错误重传等问题)和流量控制。

第三,网络层 上使用IP协议用于网际间的传输。网络层将运输层传递过来的报文段进行包装为数据报,为其添加IP首部,包括源IP地址、目标IP地址等信息。网络层主要是为数据进行逻辑编址,这样数据就能从一个网络传递到另一个网络。

第四,数据链路层 主要进行物理编址,将网络层传递过来的数据报进行包装成帧,为其添加首部,也会添加尾部。数据链路层主要通过地址解析协议ARP为数据添加发送端地址和接收端地址,一般为硬件的MAC地址,这样就可以为数据的传输提供一条可靠的数据链路。注意,一条报文传递时可能要经过多条数据链路,所以它会根据数据传递的具体路径不断进行物理编址。

第五,物理层 上通过物理介质传递比特流数据。

根据以上的五个层次,一计算机上的应用要发送数据到另一计算机上的应用,其过程如下图所示:

应用层上的数据通信
来源:《TCP/IP协议族 (第4版)》

上图有几点需要进行说明:

  • 在发送端应用将报文按照由高到低的顺序从应用层传递到物理层,每一层都会给数据添加首部或者尾部信息;而经过传输到达目标地址后会由低到高逐层对数据进行“解包”,最终达到应用层的数据便是发送的完整报文;
  • 网络间数据的传输可能要经过多个不同的网络,要经过“多跳”才可能达到目标地址。在每一跳发送数据前,会先通过路由表确定下一跳的逻辑地址,并通过地址解析协议确定物理地址。之后数据报被包装成帧,这样数据就可以通过物理层进行传输;
  • 在某一跳的局域网内,所有设备都会收到帧,但出了目标路由器外其他都会丢弃该帧。之后路由器打开帧成为数据报,发现目标IP地址不是自己,就会按照上一步的步骤确定下一跳的逻辑地址和物理地址,并重新将数据报包装成帧,之后在物理层进行传递。最终数据被传递到目标地址。

一个简单的例子

为了对上述过程有一个更加直观的认识,这里挑选一个日常生活中的例子进行说明。假设有以下的场景:

甘肃的小P网上购物,在淘宝上买了几本书,需要从上海进行发货。店主小A和小P协商发货方式,由于双方附近都有顺丰网点,所以他们决定使用顺丰快递,这样小A能很快地将书交给附近的网点1,小P也能很方便地从附近的网点2拿到书。

上海的网点1收到小A要寄的书后准备发货。但是该网点发现要发往甘肃没有直通的路线,必须进行中转。OK,那就中转吧。该网点的工作人员查询后发现,可以先将包裹发往成都的网点3。那好,在包裹上盖几个章写明寄件人、收件人、发货网点、收货网点等信息后,上海网点1的工作人员将包裹发出。

上海网点1 -> 成都网点3

过了一天,成都网点3收到了该包裹,发现是发给自己网点的。既然是给自己的,那打开包裹看一下有什么信息呢?通过工作人员的查询,虽然该包裹发到了成都网点3,但是收件人地址并不是这里,而是甘肃某地。工作人员略微考虑了一下,认为该包裹应该是经这个网点中转。那就再转发吧。通过查询,工作人员发现有一条直达甘肃的路线,但也并不能直接到收货人手里。所以成都网点3的工作人员在包裹上盖几个章写明寄件人、收件人、发货网点、收货网点等信息后,又将包裹发出。

成都网点3 -> 甘肃网点4

经过漫长的等待,甘肃的网点4收到了该包裹。经过查询发现这个包裹还是一个中转包裹。所幸,由于是省内的包裹,所以网点4可以直接发到收件人所在的网点2。之后,填写相关信息后该网点就将包裹发出了。

甘肃网点4 -> 甘肃网点2

再经过几天,甘肃的小A终于收到了包裹。这真是一次漫长的网购啊~

注:以上图例中网点可以看作是物理地址,A和P可以看作是IP地址。

后续继续更新,敬请期待……


版权声明

Learn Python by Fan Chunke is licensed under a Creative Commons BY-NC-ND 4.0 International License.

Fan Chunke创作并维护的Learn Python博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证

本文首发于Learn Python 博客( http://fanchunke.me ),版权所有,侵权必究。


本文永久链接:http://fanchunke.me/uncategorized/一次HTTP请求的完整过程分析/

坚持原创技术分享,您的支持将鼓励我继续创作!