浏览器地址栏里输入URL后的全过程

7,941 阅读8分钟

什么是URL

URL统一资源定位符(Uniform Resource Locator),是资源标识最常见的形式。URL描述了一台特定服务器上某资源的特定位置。它们可以明确说明如何从一个精确、固定的位置获取资源。

URL说明了协议、服务器和本地资源。

而浏览器都是基于HTTP协议,而HTTP是个应用层的协议。HTTP无需操心网络通信的具体细节都交给了TCP/IP
TCP:

  • 无差错的数据传输。
  • 按序传输(数据总是按照发送的顺序到达)。
  • 未分段的数据流(可以在任意时刻将数据发送出去)。

HTTP协议位于TCP的上层。HTTP使用TCP来传输其报文数据。

HTTP

解析URL

当用户输入一个完整的URL之后,浏览器就开始解析URL的构成,以便于查找资源地址,大多数URL的语法通用格式如下:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

基本上没有哪个URL包含了所有这些组件。URL最重要的3个部分是方案scheme,主机host和路径path
如果URL中不包含port,浏览器会默认使用80端口进行访问。

DNS域名解析

什么是DNS?

DNS( Domain Name System)是“域名系统”的英文缩写,DNS是应用层协议,事实上他是为其他应用层协议工作的,包括不限于HTTP和SMTP以及FTP,用于将用户提供的主机名解析为ip地址。

DNS 查询的过程如下图所示。

  • 在浏览器中输入www.qq.com 域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。

  • 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。

  • 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。

  • 如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。

  • 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(http://qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找http://qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。

  • 如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是的交互查询就是迭代查询。

建立TCP连接

TCP根据不同的当前状态(常规或加星)所发送的内容:

常规状态 说 明 发 送 加 星 状 态 发 送
CLOSED 关闭 RST, ACK
LISTEN 监听连接请求(被动打开)
SYN_SENT 已发出SYN (主动打开) SYN SYN_SENT* SYN, FIN
SYN_RCVD 已经发出和收到SYN;等待ACK SYN, ACK SYN_RCVD* SYN, FIN, ACK
ESTABLISHED 连接已经建立(数据传输) ACK ESTABLISHED* SYN, ACK
CLOSE_WAIT 收到FIN,等待应用程序关闭 ACK CLOSE_WAIT* SYN, FIN
FIN_WAIT_1 已经关闭,发出FIN;等待ACK和FIN FIN, ACK FIN_WAIT_1 SYN, FIN, ACK
CLOSING 两端同时关闭;等待ACK FIN, ACK CLOSING* SYN, FIN, ACK
LAST_ACK 收到FIN已经关闭;等待ACK FIN, ACK LAST_ACK* SYN, FIN, ACK
FIN_WAIT_2 已经关闭;等待FIN ACK
TIME_WAIT 主动关闭后长达2 M S L的等待状态 ACK

TCP中定义了7个扩展状态,这些扩展状态都称为加星状态。它们分别是:SYN_SENT*SYN_RCVD*ESTABLISHED *CLOSE_WAIT *LAST_ACK *FIN_WAIT_1 *CLOSING *

TCP输入的处理顺序

TCP协议收到报文段时,对其中所携带的各种控制信息 ( SYNFINACKURGRST 标志,还可能有数据和选项 )的处理顺序不是随意的,也不是各种实现可以自行决定的。

CLOSED状态到SYN_SENT状态的变迁就标明发送了一个SYN报文段。在图中则没有采用这种标记方法,而是在每个状态框中标出处于该状态时要发送的报文段类型。例如,当处于SYN_RECV状态时,要发出一个带有 SYN 的报文段,其中还包括对所收到SYN的确认( ACK )。而当处于CLOSE_WAIT状态时,要发出 对所收到FIN的确认( ACK )。

我们之所以要这样做是因为,在TCP协议中我们经常需要处理可能造成多次状态变迁的 报文段。于是在处理一个报文段时,重要的是处理完报文段后连接所处的最终状态,因为它决定了应答的内容。而如果不使用TCP协议,每收到一个报文段通常至多只引起一次状态 变迁,只有在收到SYN/ACK报文段时才是例外。

三次握手

客户端和服务器之间建立连接需要经过三次确认的阶段,我们称之为TCP的三次握手。

第一次

客户端发送一个syn报文,设置发送序号为X,客户端进入SYN_SENT状态,等待服务器回应。

第二次

服务端收到syn报文,但是服务端必须确定客户端的syn(ack= X + 1), 因此服务端也要发送一个syn=Y给客户端进行确认,表示服务端已经收到客户端的请求。
服务端需要发送ack+syn给客户端,此时服务器进入SYN_RECV状态。

第三次

客户端收到服务器的syn+ack包,向服务器发送确认包ack(ack=Y+1),此包发送完毕,客户端和服务器进入ESTABLISHEDTCP连接成功)状态,完成三次握手。

举个例子

比如你走在路上,发现前面有你的朋友向你走过来,你向你朋友挥手(第一次握手)。

你朋友看见了你向他打招呼,但是你朋友因为距离你太远,并不确定是否是跟他打招呼的,因此,你朋友用手指了下自己,并向你示意(第二次握手)。

你看见了你朋友的表情和动作,你需要给你朋友一个肯定,此时,你点头示意(第三次握手)。

此时你和你朋友互相聊天(TCP已连接)。

四次挥手

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。

这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。

首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

  • TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
  • 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
  • 服务器关闭客户端的连接,发送一个FIN给客户端。
  • 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。

挥手例子

你和你朋友聊天,聊着聊着,突然想起来女朋友钥匙丢了,你是回家开门的,现在耽误了半小时了,吓得冷汗都出来了,一想起榴莲。。。

这个时候,你赶紧跟你朋友说了情况,你说你马上得回去了,下次再聊(第一次挥手)。

你朋友听了,觉得也是得赶紧回去,就跟你说你赶紧回去吧。(第二次挥手)。

然后,你朋友走了,并向你挥手道别(第三次挥手)。

你看见你朋友跟你道别,你同样也跟你朋友道别(第四次挥手)。

回去之后,你就需要玩玩你的榴莲了。

页面渲染

查看下篇文章 浏览器渲染原理(性能优化之如何减少重排和重绘)

最后

参考文章:

1、HTTP权威指南。

2、DNS原理及其解析过程【精彩剖析】

3、TCP-IP详解卷