<<^^>>努力不一定有回报,不努力一定没有回报。

信息展示

昵称:aliveto 邮箱:some_body@foxmail.com

当你在浏览器地址栏输入一个URL后回车,将会发生的事情?

当我们在浏览器的地址栏输入 www.aliveto.cn ,然后回车,回车时页面到底发生了什么呢?下面是发生的步骤:

名解析 –>

发起TCP的3次握手 –>

建立TCP连接后发起http请求 –>

服务器响应http请求,浏览器得到html代码 –>

浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) –>

浏览器对页面进行渲染呈现给用户

一.域名解析

首先Chrome浏览器会解析www.aliveto.cn这个域名对应的IP地址。怎么解析到对应的IP地址?

  1. Chrome浏览器会首先搜索浏览器的DNS缓存(缓存时间比较短,TTL默认是1000,且只能容纳1000条缓存),看自身的缓存中是否有www.aliveto.cn对应的条目,而且没有过期,如果有且没有过期则解析到此结束。

    注:我们怎么查看浏览器的DNS缓存?可以使用 chrome://net-internals/#dns 来进行查看

  2. 如果浏览器自身的缓存里面没有找到对应的条目,那么Chrome会搜索操作系统的DNS缓存,如果找到且没有过期则停止搜索解析到此结束。

    注:怎么查看操作系统的DNS缓存,以Windows系统为例,可以在命令行下使用 ipconfig /displaydns 来进行查看

  3. 如果在Windows系统的DNS缓存也没有找到,那么尝试读取hosts文件(位于C盘Windows下System32下drivers下etc)看看这里面有没有该域名对应的IP地址,如果有则解析成功。
  4. 如果在hosts文件中也没有找到对应的条目,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器(一般是电信运营商提供的,也可以使用像Google提供的DNS服务器)发起域名解析请求。(通过的是UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址),运营商的DNS服务器首先查找自身的缓存,找到对应的条目,且没有过期,则解析成功。如果没有找到对应的条目,则有运营商的DNS代我们的浏览器发起迭代DNS解析请求,它首先是会找根域的DNS的IP地址(这个DNS服务器都内置13台根域的DNS的IP地址),找打根域的DNS地址,就会向其发起请求(请问www.aliveto.cn这个域名的IP地址是多少啊?),根域发现这是一个顶级域cn域的一个域名,于是就告诉运营商的DNS我不知道这个域名的IP地址,但是我知道cn域的IP地址,你去找它去,于是运营商的DNS就得到了cn域的IP地址,又向cn域的IP地址发起了请求(请问www.aliveto.cn这个域名的IP地址是多少?),cn域这台服务器告诉运营商的DNS我不知道www.aliveto.cn这个域名的IP地址,但是我知道www.aliveto.cn这个域的DNS地址,你去找它去,于是运营商的DNS又向www.aliveto.cn这个域名的DNS地址(这个一般就是由域名注册商提供的,像万网,新网等)发起请求(请问www.aliveto.cn这个域名的IP地址是多少?),这个时候aliveto.cn域的DNS服务器一查,果真在我这里,于是就把找到的结果发送给运营商的DNS服务器,这个时候运营商的DNS服务器就拿到了www.aliveto.cn这个域名对应的IP地址,并返回给Windows系统内核,内核又把结果返回给浏览器,终于浏览器拿到了www.aliveto.cn对应的IP地址,该进行一步的动作了。

    注:递归搜索 – DNS服务器从跟域名服务器开始进行递归搜索,从.cn顶级域名服务器到aliveto的域名服务器。一般DNS服务器的缓存中会有.cn域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。

 

DNS递归解析:

DNS迭代解析:

二:发起TCP的3次握手

拿到域名对应的IP地址之后,User-Agent(一般是指浏览器)会以一个随机端口(1024 < 端口 < 65535)向服务器的WEB程序(常用的有tomcat,nginx等)80端口发起TCP的连接请求。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接

(1)客户端先发送一个创建连接的SYN请求,告诉服务器主机“我想和你创建一条TCP连接”。

(2)当服务器主机收到SYN请求后,如果其所请求的端口号正在等待连接,则会为这一条TCP连接分配资源,并发送一个SYNACK报文段作为应答。

(3)客户主机收到SYNACK报文段后,客户机也为该连接分配资源。此时,连接已经建立起来了。客户主机还会向服务器主机发送另一个报文段,对允许连接的报文段进行确认。这就是有名的“三次握手”

三:建立TCP连接后,客服端发起http请求

HTTP请求报文的方法是get方式,如果浏览器存储了该域名下的Cookies,那么会把Cookies放入HTTP请求头里发给服务器。

四:服务器端响应http请求,浏览器得到html代码

服务器端WEB程序接收到http请求以后,就开始处理该请求,处理之后就返回给浏览器html文件。

五:服务器端响应http请求,浏览器得到html代码

浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源。

浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件

六、浏览器对页面进行渲染呈现给用户

不同的浏览器利用自己内部的工作机制,把请求到的静态资源和html代码进行渲染,渲染之后呈现给用户

七:断开连接,四次挥手

(1)此时TCP连接两端都还处于ESTABLISHED(established)状态,客户端停止发送数据,并发出一个FIN报文段。首部FIN=1,序号seq=u(u等于客户端传输数据最后一字节的序号加1)客户端进入FIN-WAIT-1(终止等待1)状态。

(2)服务端回复确认报文段,确认号ack=u+1,序号seq=v(v等于服务端传输数据最后一字节的序号加1),服务端进入CLOSE-WAIT(关闭等待)状态。现在TCP连接处于半开半闭状态,服务端如果继续发送数据,客户端依然接收。

(3)客户端收到确认报文,进入FIN-WAIT-2状态,服务端发送完数据后,发出FIN报文段,FIN=1,确认号ack=u+1,然后进入LAST-ACK(最后确认)状态。

(4)客户端回复确认确认报文段,ACK=1,确认号ack=w+1(w为半开半闭状态时,收到的最后一个字节数据的编号),序号seq=u+1,然后进入TIME-WAIT(时间等待)状态。

注意此时连接还没有释放,需要时间等待状态结束后(4分钟)连接两端才会CLOSED。设置时间等待是因为,有可能最后一个确认报文丢失而需要重传


  • 上一章:
  • 下一章: