小林coding图解计算机网络|基础篇02|键入网址到网页显示,期间发生了什么?

小林coding网站通道:入口
本篇文章摘抄应付面试的重点内容,详细内容还请移步:小林coding网站通道


在这里插入图片描述

孤单小弟——HTTP

  • 浏览器做的第一步工作就是解析URL
    长长的 URL 实际上是请求服务器里的文件资源。当URL没有路径名时,就代表访问根目录下事先设置的默认文件,也就是 /index.html 或者 /default.html 这些文件,这样就不会发生混乱了。
  • 生产HTTP请求信息
    URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。

一个孤单 HTTP 数据包表示:“我这么一个小小的数据包,没亲没友,直接发到浩瀚的网络,谁会知道我呢?谁能载我一程呢?谁能保护我呢?我的目的地在哪呢?”。充满各种疑问的它,没有停滞不前,依然踏上了征途!

真实地址查询——DNS

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

但在发送之前,还有一项工作需要完成,那就是查询服务器域名对应的 IP 地址,因为委托操作系统发送消息时,必须提供通信对象的 IP 地址。
有一种服务器就专门保存了 Web 服务器域名与 IP 的对应关系,它就是 DNS 服务器。

这里拿域名www.server.com进行举例,DNS 中的域名都是用句点来分隔的,这里的句点代表了不同层次之间的界限。在域名中,越靠右的位置表示其层级越高。毕竟是外国人发明的域名,他们喜欢从小大的的方式来说名一个城市的地点。

实际上域名最后还有一个点,比如 www.server.com.,这个最后的一个点代表根域名。
也就是,. 根域是在最顶层,它的下一层就是 .com 顶级域,再下面是 server.com
所以域名的层级关系类似一个树状结构:

  • 根DNS服务器(.)
  • 顶级域DNS服务器(.com)
  • 权威DNS服务器(server.com)
    域名解析的工作流程如图所示:(集体流程可查看小林coding主页
    在这里插入图片描述

那么是不是每次解析域名都要经历那么多步骤呢?

浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问「本地 DNS 服务器」。


数据包表示:“DNS 老大哥厉害呀,找到了目的地了!我还是很迷茫呀,我要发出去,接下来我需要谁的帮助呢?”

指南好帮手——协议栈

通过 DNS 获取到 IP 后,就可以把 HTTP 的传输工作交给操作系统中的协议栈。协议栈的内部分为几个部分,分别承担不同的工作。上下关系是有一定的规则的,上面的部分会向下面的部分委托工作,下面的部分收到委托的工作并执行。
在这里插入图片描述
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,这两个传输协议会接受应用层的委托执行收发数据的操作。

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

  • ICMP 用于告知网络包传送过程中产生的错误以及各种控制信息。
  • ARP 用于根据 IP 地址查询相应的以太网 MAC 地址。

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

数据包看了这份指南表示:“原来我需要那么多大佬的协助啊,那我先去找找 TCP 大佬!”

可靠传输——TCP

HTTP 是基于 TCP 协议传输的。
在这里插入图片描述


TCP传输数据之前,要先三次握手建立连接

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

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

此时,遇上了 TCP 的 数据包激动表示:“太好了,碰到了可靠传输的 TCP 传输,它给我加上 TCP 头部,我不再孤单了,安全感十足啊!有大佬可以保护我的可靠送达!但我应该往哪走呢?”

远程定位——IP

TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象

IP包头格式:
在这里插入图片描述
因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 06(十六进制),表示协议为 TCP。


假设客户端有多个网卡,就会有多个IP地址,那IP头部的源地址应该选哪个IP呢?

当存在多个网卡时,在填写源地址 IP 时,就需要判断到底应该填写哪个地址。这个判断相当于在多块网卡中判断应该使用哪个一块网卡来发送包。

这个时候就需要根据路由表规则,来判断哪一个网卡作为源地址 IP。如果匹配到了某个网卡,后续就把包发给路由器,Gateway 即是路由器的 IP 地址。


IP报文生成
在这里插入图片描述
此时,加上了 IP 头部的数据包表示 :“有 IP 大佬给我指路了,感谢 IP 层给我加上了 IP 包头,让我有了远程定位的能力!不会害怕在浩瀚的互联网迷茫了!可是目的地好远啊,我下一站应该去哪呢?”

两点传输——MAC

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

MAC包头格式

MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息。在 MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输。
一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:

  • 0800 : IP 协议
  • 0806 : ARP 协议

MAC 发送方和接收方如何确认?

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

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

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


既然知道要发给谁,如何获取对方的MAC地址?

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

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

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

ARP的缓存机制

在后续操作系统会把本次查询结果放到一块叫做 ARP 缓存的内存空间留着以后用,不过缓存的时间就几分钟。

也就是说,在发包时:

先查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。
而当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询。


MAC报文生成

在这里插入图片描述

此时,加上了 MAC 头部的数据包万分感谢,说道 :“感谢 MAC 大佬,我知道我下一步要去哪了!我现在有很多头部兄弟,相信我可以到达最终的目的地!”。 带着众多头部兄弟的数据包,终于准备要出门了。

出口——网卡

随后我们需要将数字信号转换为电信号,才能在网线上传输,负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序

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

最后网卡会将包转为电信号,通过网线发送出去。

唉,真是不容易,发一个包,真是历经千辛万苦。致此,一个带有许多头部的数据终于踏上寻找目的地的征途了!

送别者——交换机

下面来看一下包是如何通过交换机的。交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备

交换机的包接受工作

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

然后通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。

将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了,交换机的 MAC 地址表主要包含两个信息:

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

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


当MAC地址表找不到指定的MAC地址会怎么样?

地址表中找不到指定的 MAC 地址。这可能是因为具有该地址的设备还没有向交换机发送过包,或者这个设备一段时间没有工作导致地址被从地址表中删除了。

这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包。

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

数据包通过交换机转发抵达了路由器,准备要离开土生土长的子网了。此时,数据包和交换机离别时说道:“感谢交换机兄弟,帮我转发到出境的大门,我要出远门啦!”

出境大门——路由器

路由器和交换机的区别

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

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

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

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

路由器基本原理

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

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

路由器的包接收操作

首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。

如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。

查询路由表确定输出端口

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

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

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

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

在路由表中实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 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 地址。

  • 穿好头部衣服后,从网卡出去,交由交换机转发到出城的路由器,路由器就把响应数据包发到了下一个路由器,就这样跳啊跳。

  • 最后跳到了客户端的城门把守的路由器,路由器扒开 IP 头部发现是要找城内的人,于是又把包发给了城内的交换机,再由交换机转发到客户端。

  • 客户端收到了服务器的响应数据包后,同样也非常的高兴,客户能拆快递了!

  • 于是,客户端开始扒皮,把收到的数据包的皮扒剩 HTTP 响应报文后,交给浏览器去渲染页面,一份特别的数据包快递,就这样显示出来了!

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

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-05 07:48:03       4 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-05 07:48:03       5 阅读
  3. 在Django里面运行非项目文件

    2024-04-05 07:48:03       4 阅读
  4. Python语言-面向对象

    2024-04-05 07:48:03       5 阅读

热门阅读

  1. SPI456456

    2024-04-05 07:48:03       21 阅读
  2. 什么是stable diffusion?

    2024-04-05 07:48:03       21 阅读
  3. 初识CSS

    初识CSS

    2024-04-05 07:48:03      15 阅读
  4. 设计模式-抽象工厂模式

    2024-04-05 07:48:03       25 阅读
  5. 设计模式:工厂模式和抽象工厂模式的区别

    2024-04-05 07:48:03       17 阅读
  6. 蓝桥杯备考随手记: practise05

    2024-04-05 07:48:03       19 阅读
  7. .NET 设计模式—原型模式(Prototype Pattern)

    2024-04-05 07:48:03       22 阅读
  8. 宝塔面板永久会员7.7版本不更新版本

    2024-04-05 07:48:03       15 阅读
  9. .NET 设计模式—简单工厂(Simple Factory Pattern)

    2024-04-05 07:48:03       21 阅读