键入网址到网页显示的完整过程

2.2 键入网址到网页显示,期间发生了什么? | 小林coding

说实话,前段时间我面试腾讯的时候就被问了这道题,当时回答得应该只能说大致没错,但是没说清楚一些细节,尤其是面试官追问协商缓存和强制缓存的时候,我那时候知识储备明显应该还不够,答不上来,也是有够烦的,现在在小林coding上看到了这篇八股,也是完整记录下笔记。

HTTP

解析URL

浏览器对URL进行解析后生成Web服务器的请求消息,URL里各个元素代表情况如下:

所以URL地址实际上是请求服务器里的文件资源

当没有路径名时,就代表访问根目录下事先设置的默认文件,也就是/index.html或者/default.html这些文件,就不会发生混乱了

生产HTTP请求消息

对URL解析之后,浏览器确定了Web服务器和文件名,接下来就是根据这些信息生成HTTP请求消息。

DNS——真实地址查询

通过浏览器解析URL生成HTTP消息后,就需要委托操作系统吧消息发送给Web服务器

在发送之前,需要先查询到服务器的IP地址,而DNS服务器就是用来保存Web服务器域名和IP的关系

DNS的域名都是用英语句号芬格尔的,在域名中,越靠右的位置表示层级越高

域名的层级关系类似树状结构

  • 根 DNS 服务器(.)

  • 顶级域 DNS 服务器(.com)

  • 权威 DNS 服务器(server.com

  • 根域的DNS服务器信息保存在互联网中所有的DNS服务器中

    故客户端只需要找到任意一台DNS服务器,就可以通过它找到域DNS服务器,然后一路找到某某目标DNS服务器

    域名解析过程

  • 域名解析就是将域名映射为IP地址,当客户端需要域名解析时,通过本机的DNS客户端构造一个DNS请求报文,以UDP数据报的方式发送给本地域名服务器

  • 域名解析有递归查询和递归与迭代相结合的查询,一般都是使用递归+迭代的查询,如下图

递归与迭代查询区别

递归查询:如果主机所询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户端的身份,向其他域名服务器计息发出查询请求,即替主机继续查询,而不是让主机进一步查询,故本地域名服务器只会返回两种结果,要么是所查询的IP地址,要么是报错,表示无法查询到所需的IP地址

迭代查询:当根域名服务器接收到本地域名服务器发出的迭代请求时,要么给出索要查询的IP地址,要么就告诉服务器下一步应该找哪个域名服务器进行查询,然后让本地域名服务器进行后续查询

协议栈内部分为几个部分,分别承担了不同的工作,上面的部分会对下面部分委托工作,下面部分会受到委托的工作并开始执行

不过浏览器不是每次都要经历DNS查询,它会先查看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会查看自己的缓存,如果有,就直接返回,如果没有,再去hosts文件看,如果也没有,才会进入到本地域名服务器

传输过程——协议栈

通过DNS获取到IP后,就可以把HTTP的传输工作交给操作系统的协议栈

应用程序通过调用Socket库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的TCP和UDP协议,这两个传输协议会接受应用层的委托执行收发数据的操作。

协议栈的下面一半使用IP协议控制网络包收发,在互联网上传数据时,数据会被切成一块块的网络包,而将网络包发送给对方的操作就是由IP负责的

此外IP中还有ICMP协议和ARP协议

ICMP协议:用于告知网络包传送过程中出现的错误以及各种控制信息

ARP协议:用于根据IP地址查询相应的以太网MAC地址

TCP报文头部格式

IP下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发,也就是对网络栈中的信号执行发送和接收操作。

TCP——可靠传输

  • 源端口号目标端口必不可少;

  • 序号是为了解决包乱序的问题

  • 确认号 目的是确认发出去对方是否受到,如果没有收到就应该重新发送,直到送达;

  • 状态位例如SYN是发起连接,ACK是回复,RST是重新连接,FIN是结束连接

  • 窗口大小,TCP要做流量控制,通信双方各声明一个窗口(缓存大小),标识自己当前能够处理的能力

TCP三次握手建立连接

  • 一开始客户端和服务端都处于CLOSED状态,先是服务器主动监听某个端口,处于LISTEN状态

  • 然后客户端主动发起连接SYN,之后处于SYN-SENT状态

  • 服务端收到发起的连接,返回SYN,并且ACK客户端的SYN,之后处于SYN-RCVD状态

  • 客户端收到服务端发送的SYN和ACK后,发送对SYN确认的ACK,之后处于ESTABLESHED状态

  • 服务端收到ACK后,也处于处于ESTABLESHED状态

三次握手的目的是保证双方都有发送和接收的能力

TCP数据分割

如果 HTTP 请求消息比较长,超过了 MSS 的长度,这时 TCP 就需要把 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据。

数据会被以 MSS 的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。也就是在每个被拆分的数据加上 TCP 头信息,然后交给 IP 模块来发送数据。

  • MTU:一个网络包的最大长度,以太网中一般为 1500 字节。

  • MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。

TCP报文生成

TCP 协议里面会有两个端口,一个是浏览器监听的端口(通常是随机生成的),一个是 Web 服务器监听的端口(HTTP 默认端口号是 80, HTTPS 默认端口号是 443)。

在双方建立了连接后,TCP 报文中的数据部分就是存放 HTTP 头部 + 数据,组装好 TCP 报文之后,就需交给下面的网络层处理。网络包报文如下图:

IP定位

在 IP 协议里面需要有源地址 IP目标地址 IP

源地址IP,即是客户端输出的 IP 地址;

目标地址,即通过 DNS 域名解析得到的 Web 服务器 IP。

在 Linux 操作系统,我们可以使用 route -n 命令查看当前系统的路由表。

因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 06(十六进制),表示协议为 TCP。

举个例子,根据上面的路由表,我们假设 Web 服务器的目标地址是 192.168.10.200

  1. 首先先和第一条目的子网掩码(Genmask)进行 与运算,得到结果为 192.168.10.0,但是第一个条目的 Destination192.168.3.0,两者不一致所以匹配失败。

  2. 再与第二条目的子网掩码进行 与运算,得到的结果为 192.168.10.0,与第二条目的 Destination 192.168.10.0 匹配成功,所以将使用 eth1 网卡的 IP 地址作为 IP 包头的源地址。

那么假设 Web 服务器的目标地址是 10.100.20.100,那么依然依照上面的路由表规则判断,判断后的结果是和第三条目匹配。

第三条目比较特殊,它目标地址和子网掩码都是 0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。并且后续就把包发给路由器,Gateway(网关) 即是路由器的 IP 地址。

至此,网络包的报文如下

IP 层报文

MAC——两点传输

生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部

MAC 包头格式

在 MAC 包头里需要发送方 MAC 地址接收方目标 MAC 地址,用于两点之间的传输

一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:

  • 0800 : IP 协议

  • 0806 : ARP 协议

MAC地址确认

发送方的 MAC 地址获取就比较简单了,MAC 地址是在网卡生产时写入到 ROM 里的,只要将这个值读取出来写入到 MAC 头部就可以了。

接收方的 MAC 地址就有点复杂了,只要告诉以太网对方的 MAC 的地址,以太网就会帮我们把包发送过去,那么很显然这里应该填写对方的 MAC 地址。

所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。在路由表中找到相匹配的条目,然后把包发给 Gateway 列中的 IP 地址就可以了。

仅直到IP地址,但要直到对方的MAC地址就得靠ARP协议

ARP 广播

ARP 协议会在以太网中以广播的形式,对以太网所有的设备喊出:“这个 IP 地址是谁的?请把你的 MAC 地址告诉我”。

然后就会有人回答:“这个 IP 地址是我的,我的 MAC 地址是 XXXX”。

如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到对方的 MAC 地址。然后,我们将这个 MAC 地址写入 MAC 头部,MAC 头部就完成了。

需要注意的是,第一次查询后,后续操作系统会把本次查询结果放到一块叫做ARP缓存的额内存空间里面留着以后用

至此,MAC报文生成

MAC 层报文

网卡和交换机

网卡

网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。

负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序

网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列

数据包

  • 起始帧分界符是一个用来表示包起始位置的标记

  • 末尾的 FCS(帧校验序列)用来检查包传输过程是否有损坏

交换机

交换机工作在MAC层(数据链路层我的子层)

首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。

然后通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。这部分操作基本和计算机的网卡相同,但交换机的工作方式和网卡不同。

计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址(啥都接)

将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。

交换机的 MAC 地址表主要包含两个信息:

  • 一个是设备的 MAC 地址,

  • 另一个是该设备连接在交换机的哪个端口上。

交换机的 MAC 地址表

交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口

如果地址表中没有指定的MAC地址,那么就无法判断该发给那个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包。

这样做不会产生什么问题,因为以太网的设计本来就是将包发送到整个网络的,然后只有相应的接收者才接收包,而其他设备则会忽略这个包

此外,如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。

以下两个属于广播地址:

  • MAC 地址中的 FF:FF:FF:FF:FF:FF

  • IP 地址中的 255.255.255.255

路由器

网络包经过交换机之后,现在到达了路由器,并在此被转发到下一个路由器或目标设备。

这一步转发的工作原理和交换机类似,也是通过查表判断包转发的目标。

不过在具体的操作过程上,路由器和交换机是有区别的。

  • 因为路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址;

  • 交换机是基于以太网设计的,俗称二层网络设备,交换机的端口不具有 MAC 地址。

基本原理

路由器的端口具有 MAC 地址,因此它就能够成为以太网的发送方和接收方;同时还具有 IP 地址,从这个意义上来说,它和计算机的网卡是一样的。

当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。

查询路由器表确定输出端口

完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。

MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃

接下来,路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。

转发操作分为几个阶段,首先是查询路由表判断转发目标。

路由器转发

具体的工作流程根据上图,举个例子。

假设地址为 10.10.1.101 的计算机要向地址为 192.168.1.100 的服务器发送一个包,这个包先到达图中的路由器。

判断转发目标的第一步,就是根据包的接收方 IP 地址查询路由表中的目标地址栏,以找到相匹配的记录。

路由匹配和前面讲的一样,每个条目的子网掩码和 192.168.1.100 IP 做 & 与运算后,得到的结果与对应条目的目标地址进行匹配,如果匹配就会作为候选转发目标,如果不匹配就继续与下个条目进行路由匹配。

如第二条目的子网掩码 255.255.255.0192.168.1.100 IP 做 & 与运算后,得到结果是 192.168.1.0 ,这与第二条目的目标地址 192.168.1.0 匹配,该第二条目记录就会被作为转发目标。

实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 0.0.0.0 的记录表示「默认路由」。

路由器的发送操作

接下来就会进入包的发送操作

首先,我们需要根据路由表的网关列判断对方的地址。

  • 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。

  • 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点

知道对方的 IP 地址之后,接下来需要通过 ARP 协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。

路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。

接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址。还有一个以太类型字段,填写 0800 (十六进制)表示 IP 协议。

网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。

发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。

接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。

不知你发现了没有,在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。

服务端处理并返回

网络分层模型

数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。

接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。

于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP头部里面还有端口号, HTTP 的服务器正在监听这个端口号。

于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。

服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。

HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是服务器 IP 地址,目的地址是客户端 IP 地址。

然后从网卡出去,交由交换机转发到出城的路由器,一直到达客户端

于是,客户端开始扒皮,把收到的数据包的皮扒剩 HTTP 响应报文后,交给浏览器去渲染页面

最后,客户端要离开了,向服务器发起了 TCP 四次挥手,至此双方的连接就断开。

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值