一个网页是如何执行操作的?(键入网址到网页显示,期间发生了什么?)

大概的一个执行流程:

执行操作的一个步骤?(大概是这么叫吧)

①解析URL

②解析之后将http消息发给DNS

③通过DNS获取IP

④进行TCP连接

⑤IP进行远程定位,将数据封装成网络包发送给通信对象

一,解析URL

        首先先对url的组成进行一个初步了解:

eg:

如果我键入www.bilibili.com/video/BV****, 访问的就是哔哩哔哩服务器下video目录下BV号为多少多少的一个网页;

如果我键入www.bilibili.com (后面没有任何信息了),那就是访问的默认的/index.html 或者 /default.html(即服务器事先设置好的默认文件)

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

注意,此时这么一个HTTP数据包发送到浩瀚的网络中,“无亲无友,不知道谁能保护它,也不清楚自己的目的地在何处”,因此需要一个东西去引导他指向要到达的地址,即

二,真实地址查询--DNS

        DNS服务器专门存的是一个 Web 服务器域名跟 IP 的对应关系。

在发送之前,还有一项工作需要完成,那就是查询服务器域名对于的 IP 地址,因为委托操作系统发送消息时,必须提供通信对象的 IP 地址。

比如我们打电话的时候,必须要知道对方的电话号码,但由于电话号码难以记忆,所以通常我们会将对方电话号 + 姓名保存在通讯录里。

正入我们现实中的住址一样,如**省**市**区***街道***号一样,DNS中的域名也存在着这样一个层级结构,DNS 中的域名都是用句点来分隔的,比如  www.bilibili.com,这里的句点代表了不同层次之间的界限

在域名中,越靠右的位置表示其层级越高。(跟我们国人习惯相反,毕竟域名这个概念是外国人引进的嘛~~~)

根域在最底层,它的下一层是顶级域com,在下面是bilibili.com。

所以,域名的层级结构是一个树状结构:

        根DNS服务器

        顶级域DNS服务器(com)

        权威DNS服务器(bilibili.com)

根域的DNS服务器信息保存在互联网中所有的DNS服务器中。如此一来,任何DNS服务器都可以找到并访问根域的DNS服务器中。

域名解析的工作流程:

大致如图所示:

  1. 客户端首先会发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。

  2. 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.server.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器:“老大, 能告诉我 www.server.com 的 IP 地址吗?” 根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。

  3. 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.server.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”

  4. 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.server.com  的 IP 地址吗?”

  5. 顶级域名服务器说:“我给你负责 www.server.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。

  6. 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.server.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。

  7. 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。

  8. 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。

至此,我们完成了 DNS 的解析过程。

整个过程就和我们日常生活中找人问路的过程类似,只指路不带路。

那么,一个数据包在知道了目的地的情况下,要发出去,又该需要谁的帮助呢?

三,指南好帮手--协议栈

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

协议栈的内部有几个不同的组成,分别承担不同的工作。上下关系是有一定的规则,跟我们现在的领导差球不多,上级向下级委托工作,下级收到委托工作并执行

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

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

此外 IP 中还包括 ICMP 协议和 ARP 协议。

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

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

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

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

四,可靠传输--TCP

        HTTP 是基于 TCP 协议传输的,那么何为TCP协议呢?

TCP包头格式:

首先,源端口号目标端口号是不可少的,如果没有这两个端口号,数据就不知道应该发给哪个应用。

接下来有包的号,这个是为了解决包乱序的问题。

还有应该有的是确认号,目的是确认发出去对方是否有收到。如果没有收到就应该重新发送,直到送达,这个是为了解决不丢包的问题。

接下来还有一些状态位。例如 SYN 是发起一个连接,ACK 是回复,RST 是重新连接,FIN 是结束连接等。TCP 是面向连接的,因而双方要维护连接的状态,这些带状态位的包的发送,会引起双方的状态变更。

还有一个重要的就是窗口大小。TCP 要做流量控制,通信双方各声明一个窗口(缓存大小),标识自己当前能够的处理能力,别发送的太快,撑死我,也别发的太慢,饿死我。

除了做流量控制以外,TCP还会做拥塞控制,对于真正的通路堵车不堵车,它无能为力,唯一能做的就是控制自己,也即控制发送的速度。不能改变世界,就改变自己嘛。

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

在 HTTP 传输数据之前,首先需要 TCP 建立连接,TCP 连接的建立,通常称为三次握手

这个所谓的「连接」,只是双方计算机里维护一个状态机,在连接建立的过程中,双方的状态变化时序图就像这样。

TCP三次握手:

三次握手大致执行流程:

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

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

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

  • 客户端收到服务端发送的 SYNACK之后,发送 ACKACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了。

  • 服务端收到 ACKACK之后,处于 ESTABLISHED 状态,因为它也一发一收了。

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

TCP报文生成

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

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

至此,网络包的报文如下图。

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

五,远程定位(目的地)--IP

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

IP包头格式:

 

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

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

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

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

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

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

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

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

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

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

这个时候就需要根据路由表规则,来判断哪一个网卡作为源地址 IP。

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

举个例子,根据上面的路由表,我们假设 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报文生成:

        至此,网络包的报文如下图:

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

六,两点传输--MAC

最终生成的一个网络包在IP包前还有个这玩意:

再下面就是IP,TCP,HTTP了

七,出口--网卡

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

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

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

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

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

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

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

(关于交换机与路由器没有写)

最终,相互扒皮--服务器 与 客户端

数据包抵达了服务器,服务器肯定高兴呀,正所谓有朋自远方来,不亦乐乎?

服务器高兴的不得了,于是开始扒数据包的皮!就好像你收到快递,能不兴奋吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值