浏览器上输入URL后回车,到底发生了什么?
- 1 前言
- 2 解析URL形成http请求
- 3 DNS域名解析
- 4 网络协议栈封装
- 4.1 传输层
- 4.2 网络层
- 4.3 数据链路层
- 5 三次握手与四次挥手
- 6 服务器响应请求
1 前言
经过对计算机网络的学习,我们了解了网络通信的过程,熟悉了网络协议栈各个层的工作机制与作用。那么现在我们回过头来看一个问题:
- 浏览器上输入URL后回车,到底发生了什么?
为什么我们从浏览器的地址栏中输入一个域名,就能给我们返回一个画面精美的网页。在我们点击回车的一瞬间到底发生了哪些事情?今天我们就来一起探索!
历史文章:
【计网】从零开始学习http协议 —理解http重定向和请求方法
【计网】从零开始学习http协议 —深入理解cookie和session
【计网】从零开始认识https协议 — 保证安全的网络通信
【计网】从零开始理解TCP协议 — 熟悉TCP报头结构并理解三次握手与四次挥手
【计网】从零开始理解TCP协议 — 拥塞控制机制,延迟应答机制,捎带应答,面向字节流
【计网】从零开始认识IP协议 — 认识网络层,认识IP报头结构
【计网】从零开始认识IP协议 — 理解网段划分,NAT策略,私有IP和公网IP,认识公网
【计网】网络层路由过程 ,理解IP分片与组装
【计网】从零开始认识arp协议
2 解析URL形成http请求
首先输入一个URL在地址栏中:
URL的结构中主要包含了:
- 协议方案名:一般都是https协议,底层是TCP协议。
- 服务器域名:想要访问的服务器域名。后面可以通过DNS解析成IP地址
- 文件路径:想要访问服务器中的网络根目录下的哪一个资源。
浏览器做的第一步就是解析 URL 得到里面的参数,将域名和需要请求的资源分离开来,从而了解需要请求的是哪个服务器,请求的是服务器上什么资源等等。
确定了需要访问的服务器与需要获取的资源之后,就会形成https请求。
https请求报文结构如下:
- 请求行中会记录基础信息:
- 请求方法:GET或POST。GET通常用来获取资源(也可以进行传参,参数在URL后);POST可以提交数据给服务器,用来处理请求。
- URL:想要访问的服务器以及想要获取的资源路径
- http版本:表明使用的HTTP协议版本,如 HTTP/1.1 或 HTTP/2
- 请求报头提供关于客户端环境和请求本身的信息,如用户代理、接受的内容类型等。其中是以键值对的方式进行存储。
- 请求正文含要发送给服务器的数据,如表单数据
这时浏览器作为应用层的工作已经完成,接下来就是网络协议栈的工作了!
3 DNS域名解析
浏览器形成https报文之后,此时还不能进入到网络协议栈中,因为还有一项重要工作没有做:
- 目前只有目标服务器的域名,没有目标服务器的IP地址啊?这样你浏览器知道这事是谁,网络协议栈可不认识域名,网络协议栈需要IP地址!
域名并不是目标服务器真正意义上的地址,互联网上每一台计算机都有自己的 IP 地址标识着,但是 IP 地址并不方便记忆,所以才设计出了域名。
- 浏览器对域名进行解析时首先搜索浏览器的 DNS 缓存,浏览器缓存中维护着一张域名与 IP 地址的对应表;如果有目标域名,即可直接进行使用!
- 浏览器缓存中没有的话就去操作系统缓存中寻找。
- 如果还是没有,操作系统将域名发送至本地域名服务器,本地域名服务器查询自己的 DNS 缓存,查找成功则返回结果。
- 如果本地域名服务器中还是没有的话,那么就要求助上层域名服务器了。
这里引出一个域名等级的概念:
- 根域名 :
.root
或者.
,根域名通常是省略的- 顶级域名,如
.com,.cn
等- 次级域名,如
163.com
里的163
,这个是用户可以进行注册购买的- 主机域名,比如 baike.baidu.com 里的baike,这个是用户可分配的
这时,本地域名服务器求助根域名服务器,根域名分析后发现是.com
二级域名,所以就告诉本地域名服务器去.com
服务器中寻找域名对应IP,这样一级一级向下寻找,最终找到域名的对应IP地址,这时本地域名服务器将得到的 IP 地址返回给操作系统,同时自己将 IP 地址缓存起来;操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来;至此,浏览器就得到了域名对应的 IP 地址,并将 IP 地址缓存起来。
这时拥有了目的IP地址,可以进行网络协议栈的处理了!
4 网络协议栈封装
形成https请求报文之后,浏览器做完传输层工作就做完了,接下来就是操作系统网络协议栈的工作:
4.1 传输层
传输层获取到应用层的https报文,进行封装,通常是使用TCP协议,传输层TCP协议提供了一种面向连接的、可靠的字节流服务:
- 首先写入源端口号与目的端口号。目的端口号是根据URL解析得到的。
- 然后为这个报文赋予32位序号(本次报文的序号),以及32位确认序号(用来表示应答的序号)。
- 4位首部长度写入报头长度,根据实际情况写入6位标志位。
- 16位检验和用于检测报文是否被修改,16位紧急指针表示紧急数据的位置。
- 最终写完这个报头,赋予好对应的属性。
TCP传输层有许多特殊机制用来保证通信的可靠性:拥塞控制,流量控制,滑动窗口,超时重传机制…
形成TCP报文之后,继续向下传递,交给网络层进行处理。
4.2 网络层
网络层对传输层报文进行封装,网络层报头结构为:
- 根据版本号写入版本,一般是IPv4。写入报头长度。写入报文总长度(用于判断是否需要分片操作)。
- 写入这次分片的相关字段
- 写入源IP地址与目的IP地址
- 完成报头,形成完整报文,继续向下传递。
网络层发挥的作用是:数据报要通过怎样的路径(传输路线)才能到达对方主机,并传送给对方。
这个路径寻找过程类似问路,通过报文对路由器一次一次的中转路由,路由器通过自身的路由表(提前配置好的)指导下一个目标是哪一台主机,路由器最终会将报文发送到目标子网。
4.3 数据链路层
数据链路层的报头结构很简单:
- 如果知道目的IP地址的MAC地址,那么就直接形成MAC帧发送到网络中,这样一份完整的报文就形成了。
如果不知道对方的MAC地址,那么就要先进行一下arp请求,获取到目标IP地址主机的MAC地址。arp请求会形成一个MAC帧发送到网络中进行广播,最终到达目标IP地址的主机,对方发送回来一份arp应答,这时我们的操作系统就知道了对方的MAC地址,可以发送报文过去了!!!
这里需要注意三张表:
- 交换机中有 MAC 地址表用于映射 MAC 地址和它的端口:MAC 地址表是通过以太网内各节点之间不断通过交换机通信,不断完善起来的。
- 路由器中有路由表用于映射 IP 地址(段)和它的端口:路由表是各种路由算法 + 人工配置逐步完善起来的。
- 电脑和路由器中都有** arp 缓存表**用于缓存 IP 和 MAC 地址的映射关系:arp 缓存表是不断通过 arp 协议的请求逐步完善起来的。
这里就可以形成一份TCP/IP协议下是如何通信的过程了
- 首先网络层穿下来一个数据包,数据链路层分析目的IP,发现不是同一子网的机器,所以根据MAC 地址表选择发送给默认路由器。
- 路由器获取到了数据链路层的数据包,进行解包分用之后,根据目标IP与路由表进行判断下一次要去的子网对应的端口,然后通过数据链路层封装从对应端口发送出去,并更换
源IP地址
为子节点的WAN口IP。 - 这样一次次跳转,最终到达目的子网的路由器,这个路由器通过** arp 缓存表**找到目标IP地址的MAC地址,发送最终的mac帧过去。
- 最终,目的主机收到了发给自己的MAC帧,可以获取到数据包了!
总结一下:
- 网络层指定了从哪个主机(源 IP )发送到哪个主机(目的 IP )。目标 IP 地址在传输过程中不会改变,源IP地址会通过NAT机制进行及时更改,避免私有IP出现在公网中!
- 数据链路层是根据 MAC 地址在一个接一个的区间中进行传输的,每个区间内的出发地址即源 MAC 地址,每个区间内的目的地址即目的 MAC 地址。显然,随着数据的传输**,源 MAC 地址和目的 MAC 地址会不断的发生变化**。这样一次一次的转发,最终就可以将数据包发送给目标主机了!
5 三次握手与四次挥手
上面发送报文的前提是已经建立了与目标主机的TCP连接,如果是第一次进行访问,那么会进行TCP三次握手:
这里的通信过程是传输层。
- 首先客户端发送SYN请求,进行连接请求
- 服务端收到请求后,讲自己的SYN请求与客户端应答一起发送回去
- 客户端收到应答之后,也会向服务端发送应答,但这份应答对方是否收到,客户端并不在意。
三次握手有以下作用:
- 验证全双工:三次挥手可以验证网络的连通性,因为三次回收中客户端和服务端都进行了收发数据!
- 确认双方意愿:三次挥手可以保证双方都想要建立连接!可以达成一个共识!
- 成本低:四次挥手和五次挥手等不过也是为了完成前两个目的!而三次握手时成本最低的!
关闭连接时,会进行四次挥手:
- 客户端发送FIN请求本质:是告诉服务端客户端给你的数据已经发完了,没有数据再进行传输了(注意正常的ACK还是会发送的)!我断开连接了!客户端可以调用shutdown接口关闭写端,那么还可以继续读取服务端发送的数据!
- 服务端发送FIN请求:是告诉客户端给你的数据我都发完了,没有数据再写了!
四次挥手使用最小的通信成本,建立了断开连接的共识!双方都不和对方通信了!并且也知道对方不再和我进行通信了!注意:双方的连接可能不是同时断开,这取决于对方如何处理。同时断开时可以成为三次挥手。
6 服务器响应请求
浏览器的 HTTPs请求报文通过 TCP 三次握手建立的连接通道发送,可能被分片若干报文段,这些报文段在服务器的网络层进行拼装,服务器在收到这些报文段后,按照网络层报头中的报文序号与13位偏移量以原来的顺序重组请求报文。然后向上传递数据,最终在应用层,将https请求获取完整,然后处理并返回一个 HTTP 响应。当然,HTTP 响应报文也要经过和 HTTP 请求报文一样的过程!
此时浏览器上输入URL后回车,到底发生了什么?已经讲解完毕!