面试题:从输入网址到网页显示 期间发生了什么

面试题:从输入网址到网页显示 期间发生了什么

学习资源 小林coding 2022.3.28

网络拓扑模型

面试题:从输入网址到网页显示 期间发生了什么_第1张图片

HTTP

浏览器 -> 解析URL

URL 元素组成: 协议+//+服务器名称+资源(文件)路径名

URL -> 统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。

面试题:从输入网址到网页显示 期间发生了什么_第2张图片

当具体文件省略时 访问根目录下事先设置的默认文件 即为 /index.html /default.html 避免混乱

解析URL -> 浏览器确定Web服务器 文件名 -> 根据信息生成HTTP请求消息

请求报文 请求行: 方法 URL 版本

消息头: 首部字段名 字段值

消息体: 数据

响应报文 状态行:版本 状态码 短语

消息头: 首部字段名 字段值

消息体: 数据

DNS

浏览器解析URL -> 生成HTTP消息-> 查询服务器域名对应IP地址 -> 委托操作系统将信息发送给web服务器

DNS服务器 : 保存Web服务器域名 与 IP 的对应关系

域名的层级关系

用句点分割 表示不同层级的界限 越靠右 层级越高

eg: www.server.com.

. 根域名

.com 顶级域

server.com 权威DNS服务器

面试题:从输入网址到网页显示 期间发生了什么_第3张图片

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

-> 任何DNS服务器都可以找到并且访问根域DNS服务器 ->顺藤摸瓜找到其他墓表DNS服务器

DNS缓存

每次解析域名不一定会经过DNS寻路的过程

缓存: 浏览器自身对域名的缓存 -> 操作系统缓存 -> hosts文件 -> 本地DNS服务器

协议栈

DNS获取到目标IP-> 把HTTP的传输工作交给操作系统中的协议栈

协议栈 : 内部存在上下关系 上面部分向下委托工作 下面收到工作执行

面试题:从输入网址到网页显示 期间发生了什么_第4张图片

浏览器 调用socket库委托协议栈工作 -> TCP UDP协议 IP协议 -> 网卡驱动程序 -> 物理硬件网卡

IP:包含ICMP协议ARP协议

ICMP: 告知网络包传送过程中产生的错误以及各种控制信息

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

TCP协议–可靠传输

TCP报文头:

面试题:从输入网址到网页显示 期间发生了什么_第5张图片

源/目的端口号 -> 确定数据发送给目标应用

序号 -> 解决包乱序

确认号 ->确认发出去对方收到 如果没有收到 重新发送

状态位: SYN 发起连接 ACK 回复 RST 重新连接 FIN 结束连接

TCP面向连接->双方要维护连接状态->状态位包发送会改变双方连接状态

窗口大小: 流量控制 声明窗口(缓存大小)控制速度

拥塞控制 : 控制发送速度

TCP三次握手[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CAotbflt-1648436156729)(https://cdn.jsdelivr.net/gh/xiaolincoder/ImageHost/计算机网络/键入网址过程/9.jpg)]

  • 一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态。
  • 然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。
  • 服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态。
  • 客户端收到服务端发送的 SYNACK 之后,发送 ACKACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了。
  • 服务端收到 ACKACK 之后,处于 ESTABLISHED 状态,因为它也一发一收了。

保证双方都有发送和接受的能力

netstat -napt
#查看TCP的连接状态

TCP分割数据

消息过长 -> 超过MSS的长度->TCP需要把HTTP数据拆解面试题:从输入网址到网页显示 期间发生了什么_第6张图片

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

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

    单独拆分 (根据MSS)->加上TCP头信息 ->交给IP模块发送数据

    面试题:从输入网址到网页显示 期间发生了什么_第7张图片

TCP报文生成

面试题:从输入网址到网页显示 期间发生了什么_第8张图片

IP 远程定位

TCP 执行连接收发断开 -> 委托IP模块将数据封装成网络包 发送给通信对象

IP报头

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U4Mecd7C-1648436156733)(https://cdn.jsdelivr.net/gh/xiaolincoder/ImageHost/计算机网络/键入网址过程/14.jpg)]

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

  • 源地址IP,即是客户端输出的 IP 地址;
  • 目标地址,即通过 DNS 域名解析得到的 Web 服务器 IP。

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

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

根据路由表规则 判断哪个网卡作为源地址IP

route -n
#查看当前系统的路由表

Web服务器的目标地址 与 子网掩码 进行 与运算 匹配目的地

默认网关: 目标地址 子网掩码 0.0.0.0

后续把包发给路由器

再套一层结果:

两点传输 MAC

IP头部 + MAC头部

MAC包头格式

面试题:从输入网址到网页显示 期间发生了什么_第9张图片

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

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

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

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

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

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

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

获取对方MAC地址

ARP协议: 在以太网中以广播的形式 向目标设备获取MAC地址

ARP缓存

保存对方MAC地址 避免每次广播获取

arp -a
#查看缓存内容

再套一层!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khLRwtbk-1648436156737)(https://cdn.jsdelivr.net/gh/xiaolincoder/ImageHost/计算机网络/键入网址过程/21.jpg)]

网卡

此乃出口也

网络包 数字信号 -> 网卡驱动程序控制网卡 -> 网卡转换成电信号

网卡驱动从IP模块获取包 复制到网卡缓存区 接着 开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列

  • 起始帧分界符是一个用来表示包起始位置的标记
  • 末尾的 FCS(帧校验序列)用来检查包传输过程是否有损坏

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

交换机 不具备MAC地址

电信号 -> 到达网线接口 -> 交换机模块接受 -> 电信号转为数字信号 -> 根据FCS校验->正确则存到缓冲区

查询接收方MAC地址 是否在MAC地址表

MAC地址表

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

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

交换机根据MAC地址表查询 发送

如果找不到指定MAC地址

交换机将包转发到除了源端口之外的所有端口上

路由器

网络包 -> 交换机->路由器

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

路由器基本原理

路由器有MAC地址 所以可以接收发送

也具有IP地址 可以等同于计算机网卡

转发: 接收 -> 路由表查询 -> 相应端口发送

包接受操作

FCS校验 -> 是自己存入缓冲区 否则丢弃

查询路由表确定输出端口

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

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

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

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

面试题:从输入网址到网页显示 期间发生了什么_第10张图片

路由器发送

根据路由表网关列 判断对方地址

  • 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
  • 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点

知道IP -> ARP找MAC -> 通过交换机找路由器 ->层层转发

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

服务器和客户端

面试题:从输入网址到网页显示 期间发生了什么_第11张图片

补充内容

TCP建立连接可以两次握手吗?为什么?

不可以。有两个原因:

首先,可能会出现已失效的连接请求报文段又传到了服务器端

client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。

其次,两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到),也无法保证Client和Server之间成功互换初始序列号。

可以采用四次握手吗?为什么?

可以。但是会降低传输的效率。

四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。

第三次握手中,如果客户端的ACK未送达服务器,会怎样?

Server端:
由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。

Client端,两种情况:

  1. 在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的,所以服务器收到数据之后会读取 ACK number,进入 establish 状态
  2. 在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包应答。
如果已经建立了连接,但客户端出现了故障怎么办?

服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

初始序列号是什么?

TCP连接的一方A,随机选择一个32位的序列号(Sequence Number)作为发送数据的初始序列号(Initial Sequence Number,ISN),比如为1000,以该序列号为原点,对要传送的数据进行编号:1001、1002…三次握手时,把这个初始序列号传送给另一方B,以便在传输数据时,B可以确认什么样的数据编号是合法的;同时在进行数据传输时,A还可以确认B收到的每一个字节,如果A收到了B的确认编号(acknowledge number)是2001,就说明编号为1001-2000的数据已经被B成功接受。

什么是四次挥手?
  • 第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;
  • 第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
  • 第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;
  • 第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?

因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。

如果第二次挥手时服务器的ACK没有送达客户端,会怎样?

客户端没有收到ACK确认,会重新发送FIN请求。

你可能感兴趣的:(计算机网络,网络协议)