进程和线程的关系:
单进程浏览器,顾名思义就是所有的功能、模块都运行在一个进程里,在2007年以前,市面上所有的浏览器都是单进程的。毫无疑问肯定很不好使。它会出现不稳定、不流畅、不安全等状况。


分析下进程的功能
为了解决这两个问题,2016年,chrome官方团队使用SOA(面向服务的架构)设计了新的架构

在如今多进程浏览器时代下,偶尔也会出现单个页面卡死最终崩溃导致所有页面崩溃的情况,这是因为:
通常情况下是一个页面使用一个进程,但是如果几个页面符合同一站点,那么他们将被分配到一个渲染进程里面去。所以,这种情况下,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同一个渲染进程。那为什么要让他们跑在一个进程里面呢?因为在一个渲染进程里面,他们就会共享JS的执行环境,也就是说A页面可以直接在B页面中执行脚本。因为是同一家的站点,所以是有这个需求的。
首先要了解的:互联网中的数据是通过数据包来传输的。如果发送的数据很大,那么该数据就会被拆分为很多小数据包来传输。比如你现在听的音频数据,是拆分成一个个小的数据包来传输的,并不是一个大的文件一次传输过来的。
IP就是Internet Protocol – 网络协议
计算机的地址就称为 IP 地址,访问任何网站实际上只是你的计算机向另外一台计算机请求信息。
IP 头是 IP 数据包开头的信息,包含 IP 版本、源 IP 地址、目标 IP 地址、生存时间等信息。
IP是非常底层的协议,它只负责把数据包传送到对方的电脑上,具体要传给哪个程序是由UDP(User Datagram Protocol)(用户数据包协议决定的)
UDP 中一个最重要的信息是端口号,端口号其实就是一个数字,每个想访问网络的程序都需要绑定一个端口号。通过端口号 UDP 就能把指定的数据包发送给指定的程序了,所以IP 通过 IP 地址信息把数据包发送给指定的电脑,而 UDP 通过端口号把数据包分发给正确的程序。和 IP 头一样,端口号会被装进 UDP 头里面,UDP 头再和原始数据包合并组成新的 UDP 数据包。UDP 头中除了目的端口,还有源端口号等信息。
在使用 UDP 发送数据时,有各种因素会导致数据包出错,虽然 UDP 可以校验数据是否正确,但是对于错误的数据包,UDP 并不提供重发机制,只是丢弃当前的包,而且 UDP 在发送之后也无法知道是否能达到目的地。
虽说UDP 不能保证数据可靠性,但是传输速度却非常快,所以 UDP 会应用在一些关注速度、但不那么严格要求数据完整性的领域,如在线视频、互动游戏等。
对于浏览器请求,或者邮件这类要求数据传输可靠性的应用,如果使用 UDP 来传输会存在两个问题:
为了解决这两个问题,我们引入了 TCP (Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
对于数据包丢失的情况,TCP 提供重传机制;
TCP 引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件。


三次握手建立连接:
这个阶段是通过“三次握手”来建立客户端和服务器之间的连接。
传输数据:
在此阶段,接收端需要对每个数据包进行确认操作,在接收到数据包后,要向发送端发送确认数据包。
所以如果发送端发送了一个数据包,但是却没有收到回复,那么代表这个数据包丢失了。然后就会触发发送端的重发机制。
同样,一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据。
四次挥手断开连接:
- 第一次挥手:客户端发送FIN=M,用来关闭客户端到服务器端的数据传送,然后客户端就会进入FIN_WAIT_1状态,意思就是说,我没有数据要发了,但是你如果要发数据的话,还可以发给我,不用急着关闭我们之间的连接
- 第二次挥手:服务器端收到FIN=M后,发送ack=M+1,告诉客户端,我知道啦,但是,我还没准备好现在就关掉连接,请你继续等待我的消息。然后客户端就进入了FIN_WAIT_2状态,继续等待服务器端
- 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。然后服务器端进入LAST_ACK状态。
- 第四次挥手:服务器端收到了FIN=N报文,知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手
TCP 为了保证数据传输的可靠性,牺牲了数据包的传输速度,因为“三次握手”和“数据包校验机制”等把传输过程中的数据包的数量提高了一倍。
HTTP是一种允许浏览器向服务器获取资源的协议,是WEB的基础。
那么现在以http://time.geekbang.org/index.html为例,来探讨一下浏览器发起HTTP请求的流程吧
浏览器会先构建请求行信息,构建好后,浏览器准备发起网络请求
GET /index.html HTTP1.1
在真正发起请求之前,浏览器会先找找浏览器缓存(是指在本地保存资源副本,以供下次请求直接使用的技术)里有没有这个文件。

所以我们知道了,HTTP网络请求的第一步是建立TCP连接。建立TCP连接需要有IP地址和端口号,IP地址和端口号我们有吗?我们知道我们现在有一个URL地址http://time.geekbang.org/index.html,那么从这个URL地址可以获得IP地址和端口号吗?
time.geekbang.org。那么想要从域名获得IP地址,就要用到DNS(Domain Name System 域名系统)现在IP地址和端口号都已经拿到了,按理说已经可以开始建立TCP连接了,但是因为Chrome同一域名最多只能建立6个TCP连接,,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。,如果当前请求数量少于 6,会直接进入下一步,建立 TCP 连接。
排队等待结束之后,终于可以和服务器握手了,在 HTTP 工作开始之前,浏览器通过 TCP 与服务器建立连接
建立TCP连接后,浏览器就可以和服务器进行通信了。

请求送到了,接下来就轮到服务器端来处理请求信息了。
我们在命令行里输入
curl -i url

通常情况下,一旦服务器向客户端返回了请求数据,它就要关闭 TCP 连接。不过如果浏览器或者服务器在其头信息中加入了:Connection:kepp-alive,那么 TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度
当你在浏览器中打开 geekbang.org 后,你会发现最终打开的页面地址是 https://www.geekbang.org。
这两个 URL 之所以不一样,是因为涉及到了一个重定向操作。跟前面一样,我们依然可以使用 curl 来查看下请求 geekbang.org 会返回什么内容。
