从输入网址到网页显示

前言

本文为个人学习笔记的整理,其中很多借鉴了小林coding的图解网络和《网络是怎样连接的》。

“请描述一下从输入网址到网页显示的过程” 相信许多参加过软件开发岗位面试的人和学习过计算机网络的人都曾经见到过这个问题,作为一道非常经典的面试题,涵盖了计网、操作系统等基础知识,能够快速地考察面试者对相关知识的大致掌握程度。

TCP/IP 四层模型

如果想要深入了解这个过程,首先需要学习 TCP/IP 四层模型的前置知识。简单地描述起来就是,计算机之间为了能够相互通信,都需要遵守一定的规定,即 TCP/IP 四层模型。这个模型将计算机的职责分为了四层,从上往下依次为应用层、传输层、网络层、网络接口层,每一层都只需要完成各自的职责,并为上层提供支持。

通过这种方式,将一整个复杂的通信任务拆分成了若干个子任务,并分层完成,不仅使结构更清晰,更利于代码的编写和维护,也让使用过程变得更方便。

应用层

应用层是距离用户最近的协议,比如访问网页的HTTP、传输文件的FTP等等,一个个应用层协议可以理解为一个个用户所需的服务。

传输层

传输层用于负责数据的传输,有提供可靠传输的TCP和不可靠传输的UDP。

网络层

网络层负责在庞大的互联网(或局域网)中,通过IP地址找到通信目标。

网络接口层

网络接口层是通过MAC地址定位到具体的硬件设备。

大致过程

在这里插入图片描述

以客户端浏览器向服务器请求网页数据为例,整个过程可以分为客户端发送请求(服务端接收请求)和客户端接收数据(服务端发送数据)两个大过程,客户端发送请求时,是从上往下依次封装数据;而在客户端接收数据时,是从下往上依次解封数据

在互联网中传输的网络包结构为 <MAC头+IP头+TCP头+数据>,在传输的过程中,每次都会根据 MAC地址和 IP地址找到下一跳的设备(路由器/交换机),并更新下一跳的 MAC地址和 IP地址,一直到找到目标 IP 为止。

具体过程
1 应用层-HTTP

HTTP 协议本身是一个很大的模块,这里就不对其中很多内容加以描述了,后面的 TCP 模块同理,以后如果有机会可以专门写一写。

1.1 解析URL

URL:Uniform Resource Locator,统一资源定位符,在HTTP中用位置描述的方式对资源进行定位,具有规定的格式。

扩展:URL是大小写不敏感的,不信你去试一试http://BAIDU.com

扩展-与URI的区别:URI:Uniform Resource Identifier,统一资源标识符。URI是用于标识唯一资源的,URL是URI的一种。就像我们的身份证号和空间坐标,3303…1234和XX学校三年二班五排六列这两种标识方式都属于URI,而URL是后一种方式。

HTTP 协议规定URL的格式为:http:+//+服务器/+目录名/文件名,比如http://127.0.0.1/blog/example.html,就是请求127.0.0.1这台服务器下的blog目录下的example.html文件,其中由于IP地址不方便记忆,所以常常使用域名代替,然后需要使用 DNS 查询到相应的 IP 地址,才能正常使用。

扩展:Apache、Nginx 等主流的Web服务器,都支持设置默认目录、默认请求文件等等功能,比如访问http://mu-mu.cn/就能访问主页,实质上访问的是服务器的/www/wwwroot/mu-mu.cn/blog/index.html文件,从而缩短URL和避免漏输导致无法访问。还有设置规则、转发等等许多功能。

1.2 DNS-通过域名查询IP

DNS,Domain Name System,域名系统。将域名和 IP 地址进行关联。

扩展-为什么不直接使用域名,而是非要将域名转化为IP进行使用?

因为使用IP地址进行寻址可以极大地提升效率,IP 为固定 4 字节长度,而域名为可变的 0~255 字节长度。

DNS 服务器用于保存服务器域名和 IP 之间的对应关系。DNS解析指的就是向 DNS 服务器查询对应的 IP 地址。

域名具有层级关系,从右往左层级依次降低,用句号分割。另外,实际上域名最右边有一个被省略的句号,即根域,就像 Linux 中文件系统中的根目录。比如www.mumu.cn,实际上是www.mumu.cn.

在这里插入图片描述

域名解析的过程:首先访问本地 DNS 服务器,如果查询不到目标域名,则会从根域一层层往下,直到找到对应 DNS 服务器为止,即可获得相应的 IP 地址。

扩展-DNS请求:DNS 也是应用层协议,和 HTTP 类似,但是是依靠 UDP 传输的,端口号为 53。

扩展-本地DNS服务器:本地 DNS 服务器一般是网络运营商的服务器地址,或者为路由器设置的地址。主要用于向权威 DNS 获取解析记录,并缓存解析结果。

扩展-DNS缓存:除了本地 DNS 服务器会有 DNS 缓存之外,浏览器也会有,还有 hosts 文件中保存的静态解析。比如更改了域名解析后,往往要等待几分钟才能生效,就是因为这些缓存的存在。

1.3 产生HTTP请求信息

HTTP 的请求报文和响应报文都有固定的格式以及字段,其中包含许多请求信息和响应信息,发送的具体数据也包含其中。

2 传输层-TCP
2.1 建立连接

在这里插入图片描述

TCP 建立连接的过程称为三次握手,指的是 TCP 连接的建立需要收发三个包。具体状态和包的特殊内容如图所示。

  1. 开始时,服务端处于 LISTEN 状态,即随时监听,等待连接请求。
  2. 客户端主动发起连接,需要发送 SYN=1 的标志和一个随机序列 seq=x,随后进入 SYN_SENT 状态。
  3. 服务端收到第一个包后,需要返回确认包,来证明自身具备收发数据的能力。确认包中需要有 SYN=1 和 ACK=1 的标志位, AckNum=x+1 的确认序号和随机序列 seq=y,随后进入 SYN_RCVD 状态。
  4. 客户端接收到确认包后,也需要返回一个确认包,来证明自身也具备收发数据的能力。确认包中需要有 ACK=1 的标志位, AckNum=y+1 的确认序号,随后进入 ESTABLISHED 状态。
  5. 服务端收到最后一个确认包后,也进入 ESTABLISHED 状态,连接建立成功,可以开始收发数据了。

扩展-三次握手的目的:为了确保双方都具备收发数据的能力。

2.2 收发数据

在这里插入图片描述

收发数据过程分为发送数据确认数据两步。

发送数据时,如果数据较长,TCP 会将数据拆分成一块块,放入到单独的网络包中,并加上 TCP 头进行依次发送。发送出去的 TCP 头部中有序号和包大小两个字段。

在这里插入图片描述

接收数据时,需要返回一个包进行确认操作,返回包中的 ACK 号需要为收到包的序号+长度,否则将不能通过发送方的验证,视为接收失败。

扩展-合并确认:由于每次接收数据都要额外发送一个包进行确认,会降低收发数据的效率,所以支持合并发送 ACK 包,比如发送 ACK号为4381,就能代表1~4381的数据全部接收完毕。

2.3 断开连接

在这里插入图片描述

TCP断开连接的过程称为四次挥手,双方都可以主动断开连接。接下来以客户端主动断开连接为例进行说明。

  1. 客户端发送一个 FIN 标志为1,随机序列 seq=x 的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。进入 FIN_WAIT_1 状态。
  2. 服务端确认客户端的 FIN 包,发送一个 ACK 为1,AckNum=x+1的确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接
  3. 服务端发送一个 FIN 标志为1,随机序列 seq=y 的包,表示自己也准备好关闭连接了。进入 LAST_ACK 状态。
  4. 客户端接收到来自服务端的关闭请求,发送一个 ACK 为1,AckNum=y+1的确认包,并进入 TIME_WAIT 状态,等待可能出现的要求重传的 ACK 包。
  5. 服务端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
  6. 客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。

扩展:为什么需要四次握手?

四次握手中,FIN 包表示自身已经完成数据的发送,可以关闭连接了;ACK 包表示已经接收并确认对方的 FIN 包。和三次握手类似,都需要确认双方都可以关闭连接才能够断开。

扩展:为什么需要 TIME_WAIT 状态?为什么需要等待 2MSL 时间才能关闭连接?

为了保证最后 ACK 包的送达。如果被动关闭方没有收到最后一个 ACK 包,会超时重发 FIN 包。2个MSL的时间,就是网络包一来一回的时间。

3 网络层+网络接口层

上面讲的 TCP 建立连接、收发数据、断开连接,其实都是一个个网络包的收发,虽然讲起来好像是直接从 A 到 B 一样简单,但是实际上却是在茫茫互联网中找到某一个目标这样庞大的任务,这个任务就是由网络层和网络接口层负责的。

在经过传输层的处理后,数据的格式为 <TCP头+数据>,继续依次经过网络层和网络接口层的处理后,数据的格式就变成了 <MAC头+IP头+TCP头+数据>,随后,就可以交给交换机/路由器等设备,去寻找最终的目的地了。

这里需要注意,虽然我们在说 DNS 的时候提到,HTTP 请求的目的地是某一个 IP 地址,但是实质上,我们还需要通过这个 IP 地址找到对应的 MAC 地址,最终再通过这个 MAC 地址找到目标。IP 地址是网络运营商分配给每个网卡的,而 MAC 地址则是每个网卡出厂就确认的,这就意味着 IP 地址是动态变化的,而 MAC 地址是不变的,也就是我们寻找的依据。

扩展-ARP:就像 DNS 负责把域名转化为 IP 一样,ARP(Address Resolution Protocol,地址解析协议)负责根据 IP 地址获取 MAC 地址。

随后,网络包的出入口:网卡,会将二进制的网络包(数字信号)转化为电信号/光信号,通过网线发送到目标网卡。然后经过若干个交换机和路由器等设备的转发,才能到达目标。

转发网络包的过程,就是将包拆解,获取 MAC头和 IP头,然后查找路由表,找到下一跳的 IP地址和 MAC地址,再将新的地址写入到包头,随后将新的网络包再次发送出去。

经过多次转发抵达目标服务器后,服务器会逐层拆解包并验证,获取到 HTTP 请求数据,再根据请求信息返回网页数据,再进行一次数据传输,把数据发回到客户端,随后客户端浏览器接收到的网页数据,就能进行渲染和显示了。

至此,一个小小的 HTTP 请求才算完结了,虽然我们平时发送请求的时候说起来很容易,代码写起来也很简单,但是其实当中有好多学问,更是有数不尽的前人帮我们完成了许多工作。

最后

本文以 TCP/IP 四层模型的角度分解了一下 “从输入网址到网页显示的过程” 这个问题,尽量还原了一下这个过程,但是仍然感觉有许多不足。

另外,除了文中提到的内容外,其实还有很多内容都没机会说,像 HTTP、TCP、IP 协议的详细知识,整个过程中浏览器的作用,交换机/路由器是如何工作的,网络和通信的内容,服务器的防火墙、负载均衡服务器、缓存服务器、DNS,操作系统的协议栈、套接字、进程线程、IO、中断等等内容,其实展开来说都是相关的内容,但是一来内容太多,篇幅太长,二来能力不够,知识有限,希望以后能有机会拿出来说说。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值