网络模型
目前公认的网络模型有两种,一种是OSI七层模型,另一种则是TCP/IP四层模型
OSI七层模型:OSI(Open System Interconnection)开放系统互连参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系。
TCP/IP四层模型:TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型。
分层作用:方便管理
OSI七层模型和TCP/IP四层模型存在一个对应关系,并且传输层以下的完全一致(TCP模型中的网络接口层就是数据链路层和物理层的集合),因此可以说将OSI模型中的会话层、表示层与应用层合并为TCP/IP模型中的应用层后,二者基本一致。
两个网络模型都属于通用网络模型,相对来说,TCP/IP模型更为普遍一些,所以我们也主要以TCP/IP模型为网络模型开展论述
我们熟知的一些协议,IP协议位于网络层,TCP协议位于传输层,而HTTP协议则位于应用层,其余还有比较熟悉的DNS协议,FTP协议等等,都有其所属的层级。
各层主要功能:
应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。
传输层:负责对报文进行分组和重组,并以TCP或UDP协议格式封装报文。(提供可靠或不可靠的传输,在重传前执行纠错 防火墙)
网络层:负责路由以及把分组报文发送给目标网络或主机。(提供逻辑地址,路由器使用它们来选择路径 三层交换机、路由器)
链路层:负责封装和解封装IP报文,发送和接受ARP/RARP报文等。(使用MAC地址提供介质访问,在设备之间传输)
TCP UDP区别
(1)TCP协议:TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,在收发数据前,必须和对方建立可靠的连接。
(2)UDP协议:UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
总结:TCP与UDP的区别:
- 1.基于连接与无连接;
- 2.对系统资源的要求(TCP较多,UDP少);
- 3.UDP程序结构较简单;UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。所以传输速度可更快
- 4.TCP保证数据正确性,UDP可能丢包;TCP保证数据顺序,UDP不保证。
场景:
udp: 视频,语音通讯使用udp,或网络环境很好,比如局域网中通讯可以使用udp。 udp数据传输完整性,可以通过应用层的软件来校对就可以了。
tcp: 传文件,数据完整性要求高。
三次握手和四次挥手
https://www.jianshu.com/p/3a40ff77d8d3
HTTP协议简介
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。
HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)
HTTP工作原理
HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据
HTTP 请求/响应的步骤:
-
- 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.baidu.com。
- 客户端连接到Web服务器
-
- 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
- 发送HTTP请求
-
- 服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
- 服务器接受请求并返回HTTP响应
-
- 释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
- 释放连接TCP连接
-
- 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
- 客户端浏览器解析HTML内容
http协议是基于TCP/IP协议之上的应用层协议
基于 请求-响应 的模式
: HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并 返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应
无状态保存
:HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议 自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个 级别,协议对于发送过的请求或响应都不做持久化处理。
无连接
:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。
(但是无连接有两种方式,早期的http协议是一个请求一个响应之后,直接就断开了,但是现在的http协议1.1版本不是直接就断开了,而是等几秒钟,这几秒钟是等什么呢,等着用户有后续的操作,如果用户在这几秒钟之内有新的请求,那么还是通过之前的连接通道来收发消息,如果过了这几秒钟用户没有发送新的请求,那么就会断开连接,这样可以提高效率,减少短时间内建立连接的次数,因为建立连接也是耗时的,默认的好像是3秒中现在,但是这个时间是可以通过咱们后端的代码来调整的,自己网站根据自己网站用户的行为来分析统计出一个最优的等待时间。)
HTTP报文结构
HTTP请求报文: 请求行(request line)、请求头部(header)、空行和请求数据(request data)
客户端发送一个HTTP请求到服务器的请求报文如下
GET /admin_ui/rdx/core/images/close.png HTTP/1.1
Accept: */*
Referer: http://xxx.xxx.xxx.xxx/menu/neo
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)
Accept-Encoding: gzip, deflate
Host: xxx.xxx.xxx.xxx
Connection: Keep-Alive
Cookie: startupapp=neo; is_cisco_platform=0; rdx_pagination_size=250%20Per%20Page; SESSID=deb31b8eb9ca68a514cf55777744e339
- 请求行数据格式由三个部分组成:请求方法、URI、HTTP协议版本,他们之间用空格分隔
GET /index.html HTTP/1.1
该部分的请求方法字段给出了请求类型,URI给出请求的资源位置(/index.html)。HTTP中的请求类型包括:GET、POST、HEAD、PUT、DELETE。一般常用的为GET和POST方式。最后HTTP协议版本给出HTTP的版本号。
- 请求头部紧跟着请求行,该部分主要是用于描述请求正文.
主要是用于说明请求源、连接类型、以及一些Cookie信息等。 (由多个key-value值组成)
3.空行:请求报文使用空行将请求头部和请求数据分隔
- 请求数据:GET方法没有携带数据,POST方法会携带一个body
HTTP响应报文: 状态行、响应头、空行、响应体(数据)
HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0xacbbb9d800005133
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html
Cxy_all: baidu+f8b5e5b521b3644ef7f3455ea441c5d0
Date: Fri, 12 Oct 2018 06:36:28 GMT
Expires: Fri, 12 Oct 2018 06:36:26 GMT
Server: BWS/1.1
Set-Cookie: delPer=0; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=1433_21112_18560_26350_27245_22158; path=/; domain=.baidu.com
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
- 状态行:状态行主要给出响应HTTP协议的版本号、响应返回状态码、响应描述,同样是单行显示
HTTP/1.1 200 OK
状态码
- 1XX 请求正在处理
- 2XX 请求成功 200 OK 正常处理 204 no content 请求处理成功但没有资源可返回 206 Partial Content 对资源的某一部分请求
- 3XX 重定向 301 Moved Permanenly请求资源的URI已经更新(永久移动),客户端会同步更新URI。 302 Found 资源的URI已临时定位到其他位置,客户端不会更新URI。
- 4XX 客户端错误 400 Bad Request 请求报文中存在语法错误,一般为参数异常。401 Unauthorized 发送的请求需要HTTP认证。403 Forbiddden 不允许访问,对请求资源的访问被服务器拒绝 404 Not Found 无法找到请求的资源,请求资源不存在。
- 5XX 服务器错误 500 Internal Server Error 服务器的内部资源出故障,服务器在执行请求时发生了错误。
- 响应头部: 主要是返回一些服务器的基本信息,以及一些Cookie值等(由多个key-value值组成)
- 空行:响应报文使用空行将响应头和响应体分隔
- 响应体:请求需要得到的具体数据,可以为任何类型数据,一般网页浏览返回的为html文件内容
在浏览器地址栏输入url到按下回车发生了什么?
1.解析url
浏览器通过地址栏捕获到url地址之后,首先对url地址进行解析.
一个完整的url,包含上述几部分,协议部分一般都是 http或者https。域名部分可以是 一段域名例如:baidu.com 也可以是 ip地址,域名最后也会被解析为ip地址。
该ip地址的作用就是在互联网中确定服务器的位置,紧接着是端口后,端口号确定的是在服务器中运行的具体的程序。路径部分表示的是在该程序中资源的具体标识,查询参数作用主要是为了发送数据。
2. DNS解析
一般域名都需要从运营商购买,因为ip地址不方便记忆,域名比较好记。域名都会和ip地址绑定,那么,在这里就需要做DNS解析,所谓DNS解析其实就是,根据域名找到其绑定的 ip地址
查找的顺序如下图
DNS的查找过程解析:
浏览器会先检查是否存在缓存,因为如果访问过一次该域名的话,会把结果缓存在浏览器中。
操作系统也会有自己的DNS缓存,但在这之前,会检查域名是否存在于本地的Hosts文件中。
路由器中也会有自己的缓存。
IPS DNS缓存 就是在客户端电脑上设置的首选DNS服务器。
-
在前边所有的情况下都没有找到缓存的情况下,会连接互联网,把请求转发到互联网的根域。
3. TCP连接
确定好目标服务器的ip地址和端口号后,就开始和远程服务器建立TCP链接https://www.jianshu.com/p/3a40ff77d8d3
TCP三次握手的好处在于的好处在于,发送方可以确认接收方仍然在线
4. 发送http请求
http协议是建立在tcp/ip协议之上的,tcp保证连接通畅,http就可以正常的进行请求和响应了。首先http请求是一个无状态的请求,且只能由浏览器主动发起,服务器进行响应。(请求报文)
5.服务器接收请求
在服务端会监听浏览器端发送的http请求,当浏览器的请求发出后,服务端就会接受该请求,并解析出相应的信息,选择对应的逻辑进行处理(比如:查找对应的静态页面,保存文件,操作数据库,转发....),并将处理的结果响应给浏览器端。
6.服务器响应
服务器执行完逻辑之后,需要给浏览器响应内容(无论是要从服务器获取数据,还是在服务器做了什么操作,都需要给浏览器一个响应)(响应报文)
服务器响应的同时肯定会伴随着浏览器端接收,等浏览器端彻底接收完毕之后,TCP就要进行4次挥手,并断开连接了。
7.TCP链接断开
TCP链接的断开需要经过"四次挥手",那么就需要一方主动的释放另外一方被动的释放。大体的过程如下:
浏览器端发消息通知服务器现在需要断开(第一次挥手)
服务器接到要断开的请求之后,给浏览器返回消息,告诉浏览器我正在准备释放(第二次挥手)
此时浏览器接到消息后正在等待服务器释放完成,而服务器正在准备释放的过程
当服务器释放完成后,再通知浏览器我已经释放完成了。(第三次挥手)
浏览器接收到服务器释放完成的消息后,再给服务器发送消息告诉服务器我已经知道你释放完成了,服务器收到消息后,就能确认自己释放完成的消息已经通知到了(第四次挥手)
8. 浏览器解析资源
当浏览器接收到服务器响应的资源后,会对资源进行解析。
首先,查看Response Header,根据响应头的指示做不同的事情,比如重定向,存储cookie,解压gzip,缓存资源等等。
接下来获取MIME类型(查看响应头的 Content-Type的值),根据不同的资源类型采用不同的解析方式
9.渲染页面
一般来说从地址栏输入地址后,绝大多是情况下响应的都是 html文件,那么就说以说页面是如何渲染html页面的,html页面中一般也会嵌入css,js,图片等资源。
因此如果解析到这些资源的时候,会再次向目标服务器发起请求,那么又会经历从解析url地址开始的各个步骤。
10.html页面的加载
首先要知道浏览器解析是从上往下一行一行地解析的。
解码:传输回来的其实都是一些二进制字节数据,浏览器需要根据文件指定编码(例如UTF-8)转换成字符串,也就是HTML 代码
预解析:预解析做的事情是提前加载资源,减少处理时间,它会识别一些会请求资源的属性,比如img标签的src属性,并将这个请求加到请求队列中。
符号化:符号化是词法分析的过程,将输入解析成符号,HTML 符号包括,开始标签、结束标签、属性名和属性值。它通过一个状态机去识别符号的状态,比如遇到<,>状态都会产生变化。
构建树:在上一步符号化中,解析器获得这些标记,然后以合适的方法创建DOM对象并把这些符号插入到DOM对象中。
浏览器的容错机制:你从来没有在浏览器看过类似”语法无效”的错误,这是因为浏览器去纠正错误的语法,然后继续工作。
11.CSS解析
一旦浏览器下载了 CSS,CSS 解析器就会处理它遇到的任何 CSS,根据语法规范解析出所有的 CSS 并进行标记化,然后我们得到一个规则表。
在匹配一个节点对应的 CSS 规则时,是按照从右到左的顺序的,例如:div p { font-size :14px }会先寻找所有的p标签然后判断它的父元素是否为div。
所以我们写 CSS 时,尽量用 id 和 class,千万不要过度层叠。
12.javaScript编译执行
主要是三个阶段
词法分析:js脚本加载完毕后,会首先进入语法分析阶段,它首先会分析代码块的语法是否正确,不正确则抛出“语法错误”,停止执行。
预编译:js有三种运行环境分别是 全局环境,函数环境,eval。每进入一个不同的运行环境都会创建一个对应的执行上下文,根据不同的上下文环境,形成一个函数调用栈,栈底永远是全局执行上下文,栈顶则永远是当前执行上下文。
执行:js虽然是单线程的,但是实际参与工作的线程一共有四个:JS引擎线程(主),事件触发线程,定时器触发线程,HTTP异步请求线程
总结
从浏览地地址栏输入地址按下回车,可以看做是一次请求的发起,那么必然会经历以下几个步骤:
解析url地址
DNS解析
TCP链接
发送http请求
服务器接收请求
服务器响应
TCP链接断开
浏览器解析资源
事件循环
浏览器执行线程
在解释事件循环之前首先先解释一下浏览器的执行线程:
浏览器是多进程的,浏览器每一个 tab 标签都代表一个独立的进程,其中浏览器渲染进程(浏览器内核)属于浏览器多进程中的一种,主要负责页面渲染,脚本执行,事件处理等
其包含的线程有:GUI 渲染线程(负责渲染页面,解析 HTML,CSS 构成 DOM 树)、JS 引擎线程、事件触发线程、定时器触发线程、http 请求线程等主要线程
关于执行中的线程:
主线程:也就是 js 引擎执行的线程,这个线程只有一个,页面渲染、函数处理都在这个主线程上执行。
工作线程:也称幕后线程,这个线程可能存在于浏览器或js引擎内,与主线程是分开的,处理文件读取、网络请求等异步事件。
任务队列( Event Queue )
所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列的机制(先进先出的机制)来进行协调
同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入任务队列。主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。
在事件循环中,每进行一次循环操作称为tick,通过阅读规范可知,每一次 tick 的任务处理模型是比较复杂的,其关键的步骤可以总结如下
- 在此次 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次)
- 检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue
- 更新 render
-
主线程重复执行上述步骤
规范中规定,task分为两大类, 分别是 Macro Task (宏任务)和 Micro Task(微任务), 并且每个宏任务结束后, 都要清空所有的微任务,这里的 Macro Task也是我们常说的 task
宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境) (process.nextTick的优先级要高于Promise.then, 在事件循环中,如果process.nextTick执行后又是process.nextTick,会继续执行,知道没有process.nextTick任务后才会去执行 Promise.then中的任务)
JavaScript 是一门单线程语言,异步操作都是放到事件循环队列里面,等待主执行栈来执行的,并没有专门的异步执行线程。
参考:
https://www.iteye.com/news/32765
https://www.cnblogs.com/itzhao/p/11242322.html
https://www.cnblogs.com/an-wen/p/11180076.html
https://blog.csdn.net/weixin_42716620/article/details/82888576
https://blog.csdn.net/snsHL9db69ccu1aIKl9r/article/details/110015266
https://blog.csdn.net/kongmin_123/article/details/82154780
https://zhuanlan.zhihu.com/p/87684858