URL是统一资源定位符,用于定位互联网上的资源,俗称网址。我们在地址栏输入网址后敲下回车,浏览器会对输入的信息进行以下判断:
1. 检查输入的内容是否是一个合法的URL连接
2. 如果合法的话,则会判断URL是否完整,如果不完整的话,浏览器可能会对地址进行猜测,补全地址的前缀或者后缀。
3. 如果不合法的话,将输入内容作为搜索条件,使用用户设置的默认搜索引擎来进行搜索。大部分的浏览器会从历史记录,书签等地方开始查找我们输入的内容,并给出智能提示。
因为浏览器不能直接通过域名找到对应的服务器IP地址,所以需要进行DNS解析,找到对应的IP地址进行访问。DNS解析域名的过程如下:
首先用户在浏览器中输入域名,操作系统会检查浏览器缓存和本地hosts文件中是否有这个网址记录,有的话就从记录里面找到对应的IP地址,完成域名的解析。
没有的话,就用TCP/IP参数中设置的DNS服务器进行查询, 如果要查询的域名包含在本地配置区域资源中,则返回解析结果,完成域名解析。
如果还没有的话再接着检查本地DNS服务器是否缓存有该网址记录,有的话就返回解析结果,完成域名解析。
如果还没有的话,本地DNS服务器会发送查询报文到根DNS服务器,根DNS服务器收到请求后,返回顶级域DNS服务器地址,然后本地DNS服务器再发送查询报文到顶级域DNS服务器,顶级域DNS服务器收到请求后,返回权威DNS服务器的地址,然后本地DNS服务器再发送查询报文到权威DNS服务器,权威DNS服务器收到请求后,返回最终的IP地址,完成域名的解析。
当浏览器获取到服务器的IP地址后,浏览器会用一个随机的端口号向服务器的80端口发起TCP连接请求,连接请求到达服务器端后,通过TCP三次握手建立TCP连接。
TCP三次握手,其实就是建立一个TCP连接。客户端与服务器交互需要3个数据包,所以叫三次握手。握手的主要作用就是为了确认双方的接收和发送能力是否正常,初始序列包,交换窗口大小等信息。
第一次握手:客户端发送SYN报文,并进入SYN_SENT状态,等待服务器的确认。
第二次握手:服务器收到SYN报文,需要向客户端发送SYN+ACK报文,此时服务器进入SYN_RCVD状态。
第三次握手:客户端收到SYN+ACK报文,向服务器发送确认包,客户端进入ESTABLISHED状态。待服务器收到客户端发送ACK包也会进入ESTABLISHED状态,完成三次握手。
那为什么TCP采用三次握手,二次握手不可以吗?
主要是因为以下原因:
1. 确认双方的收发能力。TCP建立连接之前,需要确认客户端和浏览器双方的收包和发包的能力,最开始的一次握手,客户端发送网络包,服务端收到了,这样服务端就能得出结论:客户端的发送能力,服务端的接收能力是正常的。第二次握手,服务端发包,客户端收到了,这样客户端就能得出结论:服务端的接收,发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。第三次握手:客户端发包,服务端收到了,这样服务端就能得出结论:客户端的接收,发送能力正常,服务端自己的发送,接收能力也正常。所以,只有三次握手才能确认双方的接收与发送能力是否正常。
2. 确认序列号可靠同步。如果是两次握手,服务端无法确认客户端是否已经接收到了自己发送的初始序列号,如果第二次握手报文丢失,那么客户端就无法知道服务端的初始序列号,那TCP的可靠性也就无从谈起了。
3. 阻止重复历史连接的初始化。客户端由于某种原因发送了两个不同序号的SYN包,由于网络环境的复杂性,旧的数据包有可能先到达服务器。如果是两次握手,服务器收到旧的SYN就会立刻建立连接,那么就会造成网络异常。如果是三次握手,服务器需要回复SYN+ACK包,客户端会对比应答的序号,如果发现是旧的报文,就会给服务器发RST报文,直到正常的SYN到达服务器后才正常建立连接。所以要三次握手才有足够的上下文信息来判断当前连接是否是历史连接。
4. 安全问题。TCP新建连接时,内核会为连接分配一系列内存资源,如果采用两次握手,旧建立连接,那会放大DDOS攻击的。TCP作为一种可靠的传输控制协议,其核心思想是既要保证数据可靠传输,又要提高传输的效率,而三次握手恰好可以满足以上两方面的需求。
建立连接后,就可以通过HTTP进行数据的传输了。
如果是https的话,会在TCP和HTTP之间多添加一层协议作为加密及认证的服务,HTTPS使用SSL和TLS协议保障了信息的安全。SSL协议的作用是认证客户端和服务器,确保数据发送到正确的客户端和服务器,加密数据防止数据中途被窃取,维护数据的完整性,确保数据在传输过程中不被改变。TLS协议的作用是用于在两个通信应用程序之间提供保密性和数据完整性。TLS协议由两层组成:TLS记录协议和TLS握手协议。
服务器收到请求后,将发回一个HTTP的响应报文,内容包括相关的响应头和HTML正文。
不同的浏览器引擎渲染过程不太一样。以谷歌浏览器为例。
先请求服务器得到HTML文件,处理HTML标记并构建DOM树;
然后向浏览器发送请求得到CSS文件,处理CSS标记并构建CSSOM树;
接着将DOM树和CSSOM树合并为一颗渲染树,根据渲染树来布局。
布局就是获取渲染树的结构,节点位置和大小,是依据盒子模型来进行的,每个元素都用一个盒子来表示,然后这些盒子在页面上进行排列和和嵌套,以计算每个节点的几何信息,最后将各个节点渲染到屏幕上。
第一步,浏览器发送请求以后,服务器或者本地返回给浏览器HTML文件,解析HTML文件,并且构建DOM;
第二步,在解析HTML文件的时候遇到了link标签,浏览器就去请求CSS文件,请求CSS文件的同时会继续解析HTML文件,
第三步,此时遇到了script标签,浏览器就去请求JS文件,此时服务器或者本地就会陆续返回CSS和JS文件,实际操作中会先得到CSS还是JS文件要看具体情况。必须要等到CSSOM构建完成了才能执行JS文件。
浏览器会默认开启持久连接,也就是标签页关闭的时候,TCP连接才会关闭。这个关闭的过程就是4次挥手。
最开始一次挥手,客户端发起FIN包,客户端进入FIN_WAIT_1状态。TCP规定,即使FIN包不携带数据,也要消耗一个序号。
第二次挥手,服务端端收到FIN包,发出确认包ACK,并带上自己的序号,服务器端进入了CLOSE_WAIT状态。这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务端发送的ACK后,进入了FIN_WAIT_2状态。
第三次挥手,服务器端数据发送完毕后,向客户端发送FIN包,半连接状态下服务器可能有发送了一些数据。服务器此时进入了LAST_ACK状态。
第四次挥手,客户端收到服务器的FIN包后,发出确认包ACK,此时客户端就进入了TIME_WAIT状态。此时TCP连接还没有释放,必须经过两个MSL后,才会进入CLOSED状态。而服务器端收到客户端的确认包ACK后就进入了CLOSED状态,可以看出服务器端结束TCP连接的时间要比客户端早一些。
为什么建立连接握手三次,关闭连接时需要是四次呢?
其实在TCP握手的时候,接收端发送SYN+ACK的包是将一个ACK和一个SYN合并到一个包中,所以减少了一次包的发送,三次完成握手。
对于四次挥手,因为TCP是全双工通信,在主动关闭方发送FIN包后,接收端可能还要发送数据,不能立即关闭服务器端到客户端的数据通道,所以也就不能将服务器端的FIN包和对客户端的ACK包合并发送,只能先确认ACK,然后服务器等到无需发送数据时再发送FIN包,所以四次挥手时必须是四次数据包的交互。