https
从浏览器输入域名到展示,这是一个Web开发必然要面对的问题,也是考验基本功的问题,故整理如下。
我们的网络世界,几乎都是由TCP/IP协议四层网络协议组成的,如下图所示:
在层层包装中,协议加上自己的首部,一层包一层。
链路层
也称作数据链路层或网络接口层(在第一个图中为网络接口层和硬件层),通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。
ARP(地址解析协议)和RARP(逆地址解析协议)是某些网络接口(如以太网和令牌环网)使用的特殊协议,用来转换IP层和网络接口层使用的地址。
网络层
IP是一种网络层协议,提供的是一种不可靠的服务,它只是尽可能快地把分组从源结点送到目的结点,但是并不提供任何可靠性保证。同时被TCP和UDP使用。
TCP和UDP的每组数据都通过端系统和每个中间路由器中的IP层在互联网中进行传输。
传输层
主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。
TCP为两台主机提供高可靠性的数据通信。
它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。为了提供可靠的服务,TCP采用了超时重传、发送和接收端到端的确认分组等机制。
UDP则为应用层提供一种非常简单的服务。
它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。一个数据报是指从发送方传输到接收方的一个信息单元(例如,发送方指定的一定字节数的信息)。UDP协议任何必需的可靠性必须由应用层来提供。
应用层
应用层决定了向用户提供应用服务时通信的活动。TCP/IP 协议族内预存了各类通用的应用服务。
FTP(File Transfer Protocol,文件传输协议),DNS(Domain Name System,域名系统)服务、HTTP即超文本传输协议(HyperText Transfer Protocol),这是一个简单的请求-响应协议。
基于此,浏览器发起http请求,从浏览器到服务器,各方所做的动作有:
一、DNS解析
二、TCP三次握手
三、 发起HTTP请求
四、服务器响应HTTP请求
五、浏览器解析
六、浏览器进行页面渲染
七、服务器关闭TCP连接
下面逐一介绍下。
一、DNS解析
1、搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存)
2、如果浏览器自身的缓存里面没有找到,那么浏览器会搜索系统自身的DNS缓存
3、如果还没有找到,那么尝试从 hosts文件里面去找
4、在前面三个过程都没获取到的情况下,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器(一般是电信运营商提供的,也可以使用像Google提供的DNS服务器)发起域名解析请求(通过的是UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址)
二、TCP三次握手
注意:SYN、Seq、ACK等字段都是TCP报文内的某个位置,存放的值
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
三次握手完成之后这个TCP连接就进入Established状态,就可以发起http请求了。
为什么要三次握手
1、为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
2、如果2个计算机使用的协议不一样,那是不能进行通信的,所以这个3次握手就相当于试探一下对方是否遵循TCP/IP协议,协商完成后就可以进行通信了。
三、四发起请求和接收请求,主要是对于http数据的处理,比较简单。
五、浏览器解析
浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样)。
这个时候就用上keep-alive特性,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里的顺序,但是由于每个资源大小不一样,而浏览器又多线程请求请求资源,所以从下图看出,这里显示的顺序并不一定是代码里面的顺序。
浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。
针对无状态的一些解决策略:
1、有时需要对用户之前的HTTP通信状态进行保存,比如执行一次登陆操作,在30分钟内所有的请求都不需要再次登陆。于是引入了Cookie技术。
2、HTTP/1.1想出了持久连接(HTTP keep-alive)方法。其特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态,在请求首部字段中的Connection: keep-alive即为表明使用了持久连接。
六、浏览器进行页面渲染
浏览器利用自己内部的工作机制,把请求的静态资源和html代码进行渲染,渲染之后呈现给用户,浏览器是一个边解析边渲染的过程。
1、浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。
涉及到两个概念: reflow(回流)和repain(重绘)。DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色、字体等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。
页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。
JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有资源的下载是没有必要的,所以JS是单线程,会阻塞后续资源下载。
七、服务器关闭TCP连接(四次挥手)
为什么要四次分手
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。
TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;
但是,这个时候主机1还是可以接受来自主机2的数据;
当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;
当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
假设网络是不可靠的,有可以最后一个ACK丢失。
所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。
Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。
2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
唠嗑广场
思考:投资的过程中,时间的重要性。
1、公司的成长、下滑甚至倒闭都需要时间,如果我们买入成熟、成长的公司,也不应该着急,而是等待公司每个季度、每年的数据,等待成长。
2、全国甚至全球的大环境,如果出现信用崩坏,那重塑信用、国内恢复发展,需要时间。
3、国内投资,还要看美联储的加息、降息,对于加息降息,美联储持续维持利率高位的时间也会比较久(2022年开始加息),等到降息周期,也需要时间。
相信时间,是因为相信人性,相信人会好了伤疤忘了疼,因为一直记着疼痛的话,人生会很痛苦,所以人都偏向于忘记过去的伤痛。