程序员过关斩将面试官再问你Http请求过程怼回去

68次阅读

共计 2677 个字符,预计需要花费 7 分钟才能阅读完成。

Http 介绍

超文本传输协议(HTTP,HyperText Transfer Protocol) 是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。1960 年美国人 Ted Nelson 构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext), 这成为了 HTTP 超文本传输协议标准架构的发展根基。

以上并非此次文章重点,更详细的 http 介绍请移步 www.baidu.com

Http 是一种网络协议,而且是无状态的超文本协议,基于 Tcp/Ip 协议的应用层协议。

我要 IP

当用户请求某个域名的资源,比如在浏览器敲入 http://www.qq.com 的时候,浏览器首先会根据输入的域名去查询 IP 地址。去哪查呢?这里就需要引入 DNS 的概念,可以把 DNS 看做是域名映射 IP 的账簿。
当客户端发送一个 DNS 请求的时候,首先本地的 DNS 服务器会接收到请求,会在本地先查询缓存中有没有当前域名和 IP 的映射关系,如果有则直接返回 IP 信息,如果没有,则会询问其他 DNS 服务器,这里简单说一下网络上 DNS 服务器的结构,DNS 服务器在网络上是树状结构的,存在一个根服务器,根服务器的子节点是一级域名服务器(比如 .com, .cn),一级域名服务器的子节点又称为权威(权限)DNS 服务器

当本地 DNS 服务器没有相关查询信息的时候会依照以上树的顺序查询域名和 IP 的对应关系,查到之后会缓存到本地 DNS,这个过程最终的结果就是获取到相关域名对应的 IP 地址,如果客户端输入的是 IP 地址信息,则省略了以上查询 IP 的过程了。

访问互联网的任何网站本质上都是依据 IP 来寻址的。

建立 Tcp 连接

当一个 http 请求发出之后,并且获取到了正确的服务器 IP 地址,这个时候就可以建立连接了。有一点需要明确:http 协议是基于 Tcp 协议的。所以第一步就需要建立 Tcp 连接,这个过程就是很多网络文章所说的三次握手:
Client:Hi,我是 Client。
Server:您好 Client,我是 Server。
Client:您好 Server…

这里是三次握手可以以这样的顺序来表示:client 的问 ->server 的答 ->client 的答

有的面试官无聊会问为什么是三次握手而不是两次或者四次五次呢?你可以理解,当两个人 A 和 B 要想互相联系的时候,最简单的方式就是 A 提问然后能收到 B 的回答,B 提问能收到 A 的回答。这也是三次握手的核心。

平时所说的 Tcp 是面向连接的,这里的连接其实是双方约定一定格式来进行通信的过程(包括发包的顺序,buffer 的大小等约定),在逻辑上好像是维持了一条连接而已。

我要出网关

一旦 Tcp 连接建立起来,http 请求就可以组织数据发送报文了。目前 http 协议的版本大部分是 1.1,在这个版本中有一个属性 Keep-Alive,这个属性标示要保持此 http 连接建立的 TCP 连接,默认是开启的。

网络上有文章大篇幅描述 http 的长连接信息,其实是错误的说法,长连接是针对 tcp 连接,http 连接打开 keepalive 选项只不过保持了 tcp 连接不断开而已。

HTTP 的报文大概分为三大部分。第一部分是请求行,第二部分是请求头(header),第三部分是请求体(body)。这里具体的 http 协议其他概念不再展开讨论,因为内容有点多。http 协议位于应用层,所以要发送的报文首先会把 http 协议相关的内容包含在包中,然后传给下一层。
.png)

下一层是传输层,这一层主要有两个协议:Tcp 和 Udp,http 协议选择的是 tcp 协议,tcp 会有两个端口信息,一个是源端口,一个是目标端口,比如 http 请求一般目标端口是 80。传输层把端口信息封装完毕,接着把请求包传给网络层。
.png)

网络层的协议是 IP 协议,在这一层会把源 Ip 地址和目标 IP 地址封装进去(目标 IP 就是请求的网站 ip,查询 dns 获得)。

.png)

操作系统知道了要发往的 IP 地址,会判断这个 ip 是否在本地局域网内(根据子网掩码来判断),如果不在的话,则需要网关把这个请求发送出去(网关的 ip 一般是 DHCP 协议配置的)。操作系统怎么获取网关在哪呢?这个过程基本上靠的是广播,应用的协议是 ARP 协议,当局域网内的所有设备接收到 ARP 协议的内容之后会判断 ip 是否和网关 ip 相同,如果相同就会回复,经过这个过程,系统找到了网关,获取到了网关的 MAC 地址,并把网关的 MAc 地址和本机的 MAc 地址封装进请求包,发给下一层 MAC 层, 最后网卡把消息发往网关。
.png)

MAC 地址主要用在同一个局域网内定位某个计算机,是在局域网内才有效的地址

到达目标服务器

请求包到达网关, 网关会根据消息的 MAC 地址来判断是否和自己的 mac 相同,如果相同则把消息接收下来。接着会判断消息中目标 IP,如果目标 IP 未在自己的局域网中,则需要根据自己的路由规则把消息发送给下一个相连的网关。网关和网关之间是通信的,至于网关怎么计算出最优路径这里不再展开。我们以常见的家庭路由器为例,每个路由器的网关 IP 其实是运营商给分配的,并且网络包发送出去一般都是采用修改 IP 的方式(NAT)。具体步骤:

  1. 网关检查目标 IP 是否在自己的局域网内,如果不在,则获取要传送的下一个网关 mac 和 IP,把目标 IP 和 mac 修改为下一个网关的 IP 和 mac,并把来源 IP 和 mac 修改为当前网关的 IP(外网 IP)和 mac。
  2. 下一个网关收到消息,首先检查 mac 是否和自己匹配,如果匹配接会检查目标 IP 是否在自己的局域网内,如果不在则重复以上步骤
  3. 重复以上步骤直到目标服务器所在的网关。
  4. 目标服务器所在的网关收到消息,会判断出来当前的目标 IP 在我的局域网范围,就不会在跳跃下一个网关,而是向局域网内发 ARP 请求寻找目标服务器,目标服务器收到请求会响应,网关会把具体的请求发送给目标服务器。
  5. 目标服务器收到消息会解析请求的消息,在对比完 mac 和 IP 信息之后,会得到端口的信息,目标服务器则在本机寻找监听这个端口的程序,http 服务器很有可能是 nginx 或者其他 web 服务器。
  6. 请求通过端口传送给具体的处理的程序,程序会解析 http 请求的内容,根据内容作出相应的回复。
  7. 请求按照以上所有步骤把响应返回给请求方(网关路由器会记住来源路径),至此一个 http 请求结束。

网关(路由器)之间通过路由表来决定下一个跳跃的网关地址

写在最后

以上只是 http 请求的一个大概过程,其实每一步都非常复杂,没有详细展开。比如:路由协议、ip 的分配 等等。


添加关注,查看更精美版本,收获更多精彩

正文完
 0