网络基础知识
网络模型
OSI体系结构
: 概念清楚,理论也比较完整,但复杂不实用。TCP/IP体系结构
:TCP/IP是一个四层体系结构,得到了广泛的运用。五层体系结构
: 折中OSI体系结构
和TCP/IP体系结构
,综合二者的优点,这样既简洁,又能将概念讲清楚。
五层网络体系结构
应用层
:应用层是网络协议的最高层,主要任务通过进程间的交互完成特定网络应用。应用层协议定义的是应用程序(进程)间通信和交互的规则
。如 DNS、HTTP、SMTP…
运输层
:有时也译为传输层,它负责为两台主机中的进程提供通信服务。该层主要有以下两种协议:
- 传输控制协议 (Transmission Control Protocol,TCP):提供面向连接的、可靠的数据传输服务,数据传输的基本单位是报文段(segment);
- 用户数据报协议 (User Datagram Protocol,UDP):提供无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性,数据传输的基本单位是用户数据报。
网络层
:网络层负责为分组网络中的不同主机提供通信服务,并通过选择合适的路由将数据传递到目标主机。在发送数据时,网络层把运输层产生的报文段或用户数据封装成分组
或 包
进行传送。
数据链路层
:简称为链路层
。在两个相邻节点传输数据时,将网络层交下来的IP数据报组装成帧
,在两个相邻节点之间的链路上传送帧
。
物理层
:保证数据可以在各种物理媒介上进行传输
TCP与UDP
TCP 和 UDP都是传输层协议,他们都属于TCP/IP协议族。
TCP
TCP,transmission control protocol 传输控制协议,
一种面向连接的,可靠的,基于字节流的传输层通信协议,数据传输单位是 报文段,建立连接的过程就是三次握手。
- 面向连接。三次握手 建立可靠连接
- 仅支持单播传输。只能1对1
- 面向字节流
- 可靠传输。TCP给每个包一个序号,也保证了按序接收。接收端实体对已成功收到的字节发回一个相应的确认(ACK);在合理的往返时延(RTT)内未收到确认,那么对应的数据将会被重传
- 提供拥塞控制。当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞。
TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。文件传输、接受邮件、远程登录。
UDP
user data protocol 用户数据报协议,喇叭喊人,数据传输单位是 用户数据报。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
- 面向无连接。不需要三次握手建立连接,想发数据随时发,不会对数据报文进行拆分和拼接操作
- 有单播,多播,广播的功能。
- 面向报文。UDP对应用层交下来的报文,既不合并,也不拆分。因此,应用程序必须选择合适大小的报文
- 不可靠性。不会备份数据,不关心对方是否已经正确接收
- 头部开销小,传输数据报文时是很高效。UDP 的头部开销小,只有8字节,相比 TCP 的至少20字节要少得多。在传输数据报文时是很高效的。
UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话、广播通信(广播、多播)。
TCP和UDP的区别
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输(数据顺序和正确性),使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用,例如视频会议、直播 | 适用于要求可靠传输的应用,例如文件传输 |
字节就是散乱的数据 报文就是添加了标记,封装后的数据
UDP协议为什么不可靠
- 不保证消息交付
- 不保证交付顺序
- 不跟踪连接状态
- 不进行拥塞控制
TCP的三次握手和四次挥手
三次握手
三次握手,指建立一个TCP连接时,需要客户端和服务器总共发送3个包。主要作用就是为了确认双方的接收能力和发送能力是否正常、同步连接双方的序列号和确认号,交换TCP窗口大小信息 为后面的可靠性传送做准备。
- 第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 seq = x ,此时客户端处于 SYN_SEND 状态。
- 第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 seq = y。同时会把客户端的 seq + 1 即 x + 1作为ACK 的值,表示已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。
- 第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 seq + 1 即 y + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。
那为什么要三次握手呢?两次不行吗?
- 为了确认双方的接收能力和发送能力都正常
- 如果是用两次握手,则会出现下面这种情况:
为了防止已失效的连接请求报文段突然又传送到了服务端,造成双方的不一致,导致资源的浪费
客户端发出一个SYN报文段,由于阻塞或者其他原因在网络中滞留,以至于客户端认为丢包了(其实并没有丢),于是重新发出一个SYN报文段,假设这一次顺利完成了,那么双方建立连接。
这看起来似乎没什么问题,但网络中有一个隐患,就是那个还在网络中传输的SYN报文段,如果这个SYN在连接期间被服务端收到了,那服务端只会无视它,这样就万事大吉了,但如果是在连接释放之后被收到呢?此时服务端认为有人向他发出连接请求,于是响应一个SYNACK回去,如果采用两次握手的话,那么服务器认为此时连接已经建立好了。但是当客户端收到这个SYNACK时,如果他并没有发起连接,那么他不会理睬这个SYNACK,就当没事发生过(如果客户端此时正好发起连接,那其实他也不会理睬这个SYNACK,因为确认号不对啊。)。那问题就大了,这时候服务器以为连接好了,向客户端发送数据,而客户端处于CLOSED状态,会丢弃这些包,这样就很浪费了。并且还有一个尴尬的问题,就是这个时候当客户端打算发起连接时,服务端又不理睬了,在这里尬这,他们就别想互发数据了。当然这些问题似乎不是不可解决的,当客户端发现服务端老是向自己发数据,而自己总是丢弃,可能会向服务端发一个RST(报文段的RST标记号为1),强制服务端关闭连接。但资源总归是浪费了一会了。而用三次握手就不会出现这样的问题。
四次挥手
男:“我觉得我们可能不太合适,我们分手吧,我不会再主动联系你。”(发出关闭连接的请求)
女:“你要分手,可以,但是我还没做好心理准备,可以让我再跟你说多几句话吗?”(发出ACK报文段)
(此后男生不会再主动联系女生,而女生还会联系男生)
女:“好,我该说的话都说完了,我们好聚好散吧。”(发送关闭连接的报文段)
男:“再见。”(发出ACK报文段,让女生知道我已经收到了)
(女生收到后,放下了男生,即释放了资源)
(男生在等待一段时间后,女生没有再回信,男生就默认女生已经收到最后的告别信了,于是放下女生,即释放了资源,从此不相往来(除非复合,即重新建立连接))
不开玩笑:
- 第一次挥手:若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。
- 第二次挥手:服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,但是服务端仍旧可以发送数据给客户端。
- 第三次挥手:服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。
- 第四次挥手:客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。
最后一次挥手中,客户端会等待一段时间再关闭的原因,是为了防止发送给服务器的确认报文段丢失或者出错,从而导致服务器 端不能正常关闭。
那为什么需要四次挥手呢?
TCP 使用四次挥手的原因是因为 TCP 的连接是全双工的,所以需要双方分别释放到对方的连接,单独一方的连接释放,只代 表不能再向对方发送数据,连接处于的是半释放的状态。
TCP的重传机制
TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该数据进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
TCP的拥塞控制机制
TCP的拥塞控制机制主要是以下四种机制:慢启动、拥塞避免、快速重传、快速恢复
慢启动
开始的时候不要发送大量数据,而是先测试一下网络的拥塞程度,由小到大增加拥塞窗口的大小
拥塞避免
将拥塞窗口控制为按线性增长,使网络不容易出现阻塞。
快速重传
接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)。发送方只要连续收到三个重复确认就立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
由于不需要等待设置的重传计时器到期,能尽早重传,能提高整个网络的吞吐量
快速恢复
TCP的流量控制机制
流量控制就是为了让发送方发送数据的速度不要太快,要让接收方来得及接收。TCP采用大小可变的滑动窗口进行流量控制,窗口大小的单位是字节。这里说的窗口大小其实就是每次传输的数据大小。
TCP的可靠传输机制
基于连续 ARQ 协议和滑动窗口协议。
HTTP协议
常见的HTTP请求方法
- GET: 向服务器获取数据;
- POST:将实体提交到指定的资源,通常会造成服务器资源的修改;
- PUT:上传文件,更新数据;
- DELETE:删除服务器上的对象;
- HEAD:获取报文首部,与GET相比,不返回报文主体部分;
- OPTIONS:询问支持的请求方法,用来跨域请求;
- CONNECT:要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信;
- TRACE: 回显服务器收到的请求,主要⽤于测试或诊断。
GET和POST的请求
Post 和 Get 是 HTTP 请求的两种方法,其区别如下:
- 应用场景:GET 请求是一个幂等的请求,一般 Get 请求用于对服务器资源不会产生影响的场景,比如说请求一个网页的资源。而 Post 不是一个幂等的请求,一般用于对服务器资源会产生影响的情景,比如注册用户这一类的操作。
- 是否缓存:因为两者应用场景不同,浏览器一般会对 Get 请求缓存,但很少对 Post 请求缓存。
- 发送的报文格式:Get 请求的报文中实体部分为空,Post 请求的报文中实体部分一般为向服务器发送的数据。
- 安全性:Get 请求将请求的参数放入 url 中向服务器发送,不太安全,因为请求的 url 会被保留在历史记录中。
- 请求长度:浏览器由于对 url 长度的限制,所以会影响 get 请求发送数据时的长度。
- 参数类型:post 的参数传递支持更多的数据类型。
幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。
GET
,HEAD
,PUT
和DELETE
等方法都是幂等的,而POST
方法不是
POST和PUT请求的区别
- PUT请求是向服务器端发送数据,从而修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次PUT操作,其结果并没有不同。(可以理解为是更新数据)
- POST请求是向服务器端发送数据,该请求会改变数据的种类等资源,它会创建新的内容。(可以理解为是创建数据)
HTTP 1.0 、1.1 和 2.0
HTTP 1.0和 HTTP 1.1 有以下区别
- 连接方面,http1.0 使用非持久连接, http1.1 使用持久连接,多个 http 请求复用同一个 TCP 连接。
- 资源请求方面。http1.0 中,服务器传输整个对象,不支持断点续传功能,不支持传输部分,浪费带宽;http1.1 在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content)
- 缓存方面,http1.0 缓存头 If-Modified-Since、Expires ,http1.1 则引入了更多的缓存头来控制缓存策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等
- http1.1 中新增了 host 字段指定服务器的域名。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。因此可以将请求发往到同一台服务器上的不同网站。
- http1.1 新增了很多请求方法,如 PUT、HEAD、OPTIONS 等。
管道网络传输和队头堵塞
HTTP/1.1 采用了长连接使得管道(pipeline)网络传输成为可能。
在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。但还是得按顺序,如果前面的回应特别慢,后面就会堵。这称为队头堵塞。
队头堵塞的解决方案:
(1)并发连接:对于一个域名允许分配多个长连接,那么相当于增加了任务队列,不至于一个队伍的任务阻塞其它所有任务。
(2)域名分片:将域名分出很多二级域名,它们都指向同样的一台服务器,能够并发的长连接数变多,解决了队头阻塞的问题。
HTTP 1.1 和 HTTP 2.0 的区别
二进制协议:在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”,可以分为头信息帧和数据帧。
多路复用:HTTP/2 仍然复用 TCP 连接,但是实现了多路复用。在一个连接里,客户端和服务器都可以不用按照顺序同时发送多个请求或回应,这样就避免了”队头堵塞”的问题。
标记数据包: HTTP/2 的数据包是不按顺序发送的,必须要对数据包做标记,指出它属于哪个请求。
HTTP/2 将每个请求或回应的所有数据包,称为一个数据流。每个数据流都有一个独一无二的编号。
头信息压缩:HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息,浪费带宽,影响速度。HTTP/2 引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。
服务器推送:HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源,可以减少一些延迟时间。
HTTP 2.0 增加了对 TLS 加密的支持,提高了安全性和兼容性
HTTP/2 下服务器主动推送的是静态资源,和 WebSocket 以及使用 SSE 等方式向客户端发送即时数据的推送是不同的。
keep-alive
HTTP1.0 中默认是在每次请求/应答完成后立即断开连接,这就是短连接。
当使用Keep-Alive模式时,Keep-Alive功能使客户端到服务器端的连接持续有效,这就是长连接。
- HTTP1.0版本是默认没有Keep-alive,想要保持连接,必须手动配置发送
Connection: keep-alive
,想要断开,发送Connection:close
- HTTP1.1 规定了默认保持长连接
如何建立Keep-Alive
- 客户端向服务器在发送请求报文同时在首部添加发送
Connection: keep-alive
字段 - 服务器收到请求并处理 Connection字段,并回送
Connection:Keep-Alive
字段给客户端 - 客户端接收到Connection字段,Keep-Alive连接建立成功
断开也是同理,字段换成Connection:close
Keep-Alive可以减少延迟,降低拥塞等优点,但值得住的是,长时间的Tcp连接容易导致系统资源无效占用,浪费系统资源
HTTP如何加载页面的多张图片?
- 在
HTTP 1
下,浏览器对一个域名下最大TCP连接数为6,所以会请求多次。可以用多域名部署解决。这样可以提高同时请求的数目,加快页面图片的获取速度。 - 在
HTTP 2
下,可以一瞬间加载出来很多资源,因为,HTTP2支持多路复用,可以在一个TCP连接中发送多个HTTP请求。
HTTP2的头部压缩算法HPACK
HPACK算法:在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。
- 静态字典:由 header 字段的预定义静态列表组成。
- 动态字典:以先进先出的顺序维护的 header 字段列表
- 压缩算法:
Huffman哈夫曼
编码
例如下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。
HTTP请求报文
HTTP请求报文由4部分组成: 请求⾏ 、请求头部 、空⾏、请求体
(1)请求⾏包括:请求⽅法字段、URL字段、HTTP协议版本字段。它们⽤空格分隔。例如,GET /index.html HTTP/1.1。
(2)请求头部:请求头部由关键字/值对组成,每⾏⼀对,关键字和值⽤英⽂冒号“:”分隔
- User-Agent:产⽣请求的浏览器类型。
- Accept:客户端可识别的内容类型列表。
- Host:请求的主机名,www.example.com。
(3)请求体: post put等请求携带的数据
HTTP响应报文
响应报⽂由4部分组成: 响应⾏、 响应头、 空⾏、 响应体
- 响应⾏:由网络协议版本,状态码和状态码的原因短语组成,例如 HTTP/1.1 200 OK 。
- 响应头:响应部⾸组成
- 响应体:服务器响应的数据
HTTP状态码
状态码的类别:
类别 | 原因 | 描述 |
---|---|---|
1xx | Informational(信息性状态码) | 接受的请求正在处理 |
2xx | Success(成功状态码) | 请求正常处理完毕 |
3xx | Redirection(重定向状态码) | 需要进行附加操作一完成请求 |
4xx | Client Error (客户端错误状态码) | 服务器无法处理请求 |
5xx | Server Error(服务器错误状态码) | 服务器处理请求出错 |
2XX 成功 请求被正常处理了
- 200 OK,表示从客户端发来的请求在服务器端被正确处理
- 204 No content,表示请求成功,但响应报文不含实体的主体部分。一般在服务器端不需要往客户端发送内容时使用。
- 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
- 206 Partial Content,进行范围请求。http1.0 还不支持;http1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206
3XX 重定向,浏览器需要执行某些特殊的处理以正确处理请求
302是http1.0的协议状态码,在http1.1版本的时候为了细化302状态码⼜出来了两个303和307
- 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
- 302 found,临时性重定向,表示资源临时被分配了新的 URL
- 使用场景:
- 当我们在做活动时,登录到首页自动重定向,进入活动页面。
- 未登陆的用户访问用户中心重定向到登录页面。
- 访问404页面重新定向到首页。
- 使用场景:
- 303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
- 303 状态码通常作为 PUT 或 POST 操作的返回结果,请求重定向页面的方法要总是使用 GET
- 307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
- 304 not modified,虽然被划分在 3XX 类别中,但是和重定向没有关系。
- 不是一种错误,而是告诉客户端有缓存,直接用缓存数据。返回页面的只有头部信息,没有内容,这样提高了网页的性能。
4XX 客户端错误
- 400 bad request,请求报文存在语法错误
- 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息,当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。
- 403 forbidden,表示对请求资源的访问被服务器拒绝,不能再继续进行验证,该访问是永久禁止的
- 404 not found,表示在服务器上没有找到请求的资源
5XX 服务器错误
- 500 internal sever error,表示服务器端在执行错误
- 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
- 502 bad gateway,扮演网关或代理角色的服务器 接收的响应无效。
- 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
HTTP协议的优缺点
HTTP 是超文本传输协议,它定义了客户端和服务器之间交换报文的格式和方式,默认使用 80 端口。它使用 TCP 作为传输层协议,保证了数据传输的可靠性
http的优缺点不是绝对的,在某些特定情况下显示出来的优缺点,有时优点可以是缺点,有时缺点可以是优点。
优点:
- 灵活可扩展,可以传输各种数据,传输类型由 Content-Type 加以标记
- 可靠,http基于tcp/ip,是一个可靠的连接
- 无状态,每次的请求和答复都是独立的,没有任何联系,可以减轻服务器的负担,对服务器无要求,因此可以组成集群。
缺点:
- 无状态:HTTP 是一个无状态的协议,如果后续处理需要前面的信息,则它必须重传。cookie技术为了解决这一问题
- 明文传输:协议中的报文使用的是文本形式,这就直接暴露给外界,不安全。
HTTP和HTTPS协议的区别
HTTP和HTTPS协议的主要区别如下:
- 安全性:HTTP协议是超文本传输协议,信息是明文传输的,HTTPS则是具有安全性的SSL加密传输协议;
- 端口:HTTP协议端口是80,HTTPS协议端口是443;
- HTTP协议连接很简单,是无状态的;HTTPS协议是有SSL和HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP更加安全。
HTTPS
超文本传输安全协议(Hypertext Transfer Protocol Secure,HTTPS)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,利用SSL/TLS来加密数据包。HTTPS的主要目的是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
HTTP协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议TLS/SSL具有身份验证、信息加密和完整性校验的功能,可以避免此类问题发生。
TLS/SSL的工作原理
TLS/SSL全称安全传输层协议(Transport Layer Security), 是介于TCP和HTTP之间的一层安全协议,不影响原有的TCP协议和HTTP协议,所以使用HTTPS基本上不需要对HTTP页面进行太多的改造。
TLS/SSL的功能实现主要依赖三类基本算法:散列函数hash、对称加密、非对称加密。这三类算法的作用如下:
- 散列函数:防止信息篡改,验证数据的完整性
- 对称加密算法:采用协商的秘钥对数据加密
- 非对称加密:实现身份认证和秘钥协商
综合上述算法特点,TLS/SSL的工作方式就是客户端使用非对称加密与服务器进行通信,使用对称加密实现身份的验证。
散列函数
常见的散列函数有MD5、SHA1、SHA256。该函数的特点是单向不可逆,对输入数据非常敏感,输出的长度固定,任何数据的修改都会改变散列函数的结果。
用于防止信息篡改并验证数据的完整性。
对称加密
常见的对称加密算法有AES-CBC、DES、3DES、AES-GCM等。密码的安全是保证信息安全的基础,服务器和N个客户端通信,需要维持N个密码记录且不能修改密码。
双方使用同一个秘钥对数据进行加密和解密,但有一个问题,如何保证秘钥传输的安全性,因为秘钥还是会通过网络传输的,一旦秘钥被其他人获取到,那么整个加密过程就毫无作用了。 这就要用到非对称加密的方法。
非对称加密
常见的非对称加密算法有RSA、ECC、DH等。秘钥成对出现,一般称为公钥(公开)和私钥(保密)。
用公钥加密的数据,只有对应的私钥才能解密。我们可以将公钥公布出去,任何想和我们通信的客户, 都可以使用我们提供的公钥对数据进行加密,这样我们就可以使用私钥进行解密,这样就能保证数据的安全了。
掌握公钥的不同客户端之间不能相互解密信息,只能和服务器进行加密通信,服务器可以实现一对多的的通信,客户端也可以用来验证掌握私钥的服务器的身份。
数字证书
现在的方法也不一定是安全的,因为没有办法确定得到的公钥就一定是安全的公钥。可能存在一个中间人,截取了对方发给我们的公钥,然后将他自己的公钥发送给我们,当我们使用他的公钥加密后发送的信息,就可以被他用自己的私钥解密。然后他伪装成我们以同样的方法向对方发送信息,这样我们的信息就被窃取了,然而自己还不知道。为了解决这样的问题,可以使用数字证书。
首先使用一种 Hash 算法来对公钥和其他信息进行加密,生成一个信息摘要,然后让有公信力的认证中心(简称 CA )用它的私钥对消息摘要加密,形成签名。最后将原始的信息和签名合在一起,称为数字证书。当接收方收到数字证书的时候,先根据原始信息使用同样的 Hash 算法生成一个摘要,然后使用公证处的公钥来对数字证书中的摘要进行解密,最后将解密的摘要和生成的摘要进行对比,就能发现得到的信息是否被更改了。
这个方法最要的是认证中心的可靠性,一般浏览器里会内置一些顶层的认证中心的证书,相当于我们自动信任了他们,只有这样才能保证数据的安全。
HTTPS如何保证安全
- 对称加密:简单性能也好,但是⽆法解决⾸次把秘钥发给对⽅的问题。;
- ⾮对称加密: 安全性更⾼,但是速度很慢,影响性能。
解决方案:
结合两种加密⽅式,将对称加密的密钥使⽤⾮对称加密的公钥进⾏加密,然后发送出去,接收⽅使⽤私钥进⾏解密得到对称加密的密钥,然后双⽅可以使⽤对称加密来进⾏沟通。
这又带来一个中间人问题:
如果在客户端和服务器之间存在⼀个中间⼈,中间⼈只需要把原本双⽅通信互发的公钥,换成⾃⼰的公钥,就可以轻松解密所有数据。
这时候就需要第三方颁发CA,证明身份的身份,防⽌被中间⼈攻击。证书中包括:签发者、证书⽤途、使⽤者公钥、使⽤者私钥、使⽤者的HASH算法、证书到期时间等。
如果中间⼈篡改了证书,那么身份证明是不是就⽆效了?这个证明就⽩买了,这个时候需要⼀个新的技术,数字签名。
数字签名就是⽤CA⾃带的HASH算法对证书的内容进⾏HASH得到⼀个摘要,再⽤CA的私钥加密,最终组成数字签名。当别⼈把他的证书发过来的时候,我再⽤同样的Hash算法,再次⽣成消息摘要,然后⽤CA的公钥对数字签名解密,得到CA创建的消息摘要,两者⼀⽐,就知道中间有没有被⼈篡改了。这个时候就能最⼤程度保证通信的安全了。
HTTPS通信过程
- 客户端向服务器发起请求,请求中包含使用的协议版本号、生成的一个随机数、以及客户端支持的加密方法。
- 服务器端接收到请求后,确认双方使用的加密方法、并给出服务器的证书、以及一个服务器生成的随机数。
- 客户端确认服务器证书有效后,生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数,然后发给服务器。并且还会提供一个前面所有内容的 hash 的值,用来供服务器检验。
- 服务器使用自己的私钥,来解密客户端发送过来的随机数。并提供前面所有内容的 hash 值来供客户端检验。
- 客户端和服务器端根据约定的加密方法使用前面的三个随机数,生成对话秘钥,以后的对话过程都使用这个秘钥来加密信息。
HTTPS特点
优点:身份验证、信息加密和完整性校验 记牢这三个优点就够了
缺点:
- HTTPS需要做服务器和客户端双方做加解密处理,耗费资源,过程复杂,增加页面的加载时间;
- SSL证书是收费的,功能越强大的证书费用越高
- SSL证书需要绑定IP,不能在同一个IP上绑定多个域名
在浏览器中输入 Google.com 后发生了什么?
解析URL:对URL进行解析,分析需要用的传输协议和请求资源的路径
缓存判断:浏览器判断请求的资源是否在缓存中,如果在且没有失效,直接使用,否则向服务器发起请求
DNS解析:获取URL域名的IP地址,首先会判断本地是否有该域名的IP地址缓存,如果有则使用,如果没有向本地DNS服务器发起请求。本地DNS服务器检查自己是否有缓存,如果没有向根域名服务器发起请求,得到负责的顶级域名服务器地址后,再向顶级域名服务器发请求,得到权威域名服务器的地址,再向权威域名服务器发起请求,最终得到域名的IP地址。本地DNS服务器将这个ip地址返回给用户。
用户向本地DNS服务器的请求属于递归请求;
本地DNS服务器向各个域名服务器的请求属于迭代请求
获取MAC地址:当得到IP地址后,还需要知道目的主机MAC地址。因为应用层下发数据给传输层,TCP协议指定端口,下发给网络层,网络层制定好ip地址,下发给数据链路层,需要通信双方的MAC地址。
通过ip地址与子网掩码与运算,判断主机和请求主机是否在同一个子网中,如果在同一个子网里,使用APR协议获取目的主机的MAC地址,如果不在,请求转发网关,由它代为转发,此次也可以通过ARP协议获取网关MAC地址,此次目的主机的 MAC 地址应该为网关的地址;
TCP三次握手,建立TCP连接
HTTPS握手:如果是HTTPS协议,则存在TLS的四次握手过程
返回数据:浏览器解析数据,开始渲染页面
四次挥手,中断连接
URI
URL代表资源的路径地址,而URI代表资源的名称。
URL类似于住址,它告诉你一种寻找目标的方式(在这个例子中,是通过街道地址找到一个人)。要知道,上述定义同时也是一个URI。
URL是URI的一个子集,告诉我们访问网络位置的方式
域名摸索之路
这里介绍一下我域名摸索之路:
我的ychch.top域名是在腾讯云买的,DNS服务器一开始就是用的 adonis.dnspod.net hermosa.dnspod.net 这两个,我的博客是在github.io上写的,起初通过 www CNAME ychch.github.io 解析到github主页上,但是这么做国内用户不能直接访问,所以我就换到 vercel,vercel提供免费的网站托管,国内外都可以流畅访问,我就把 ychch.top 的DNS服务器改成了vercel中的ns1.vercel-dns.com,ns2.vercel-dns.com,这一步仍然需要在 腾讯云中域名管理系统中改。
改完之后的任何解析操作(增加二级域名…) 就到 vercel 控制台 中去增改就好。
DNS解析
DNS,domain name server,域名服务器,提供一种主机名到 IP 地址的转换服务。它是一个由分层的 DNS 服务器组成的分布式数据库,是定义了主机如何查询这个分布式数据库的方式的应用层协议。
域名系统被设计成一个联机分布式的数据库系统,并采用客户/服务器模型.每个域名服务器不但能够进行一些域名到IP地址的解析,而且还必须具有连向其他域名服务器的信息。当自己不能进行域名到IP地址的转换时,能够知道到什么地方去找其他域名服务器。
DNS同时使用TCP和UDP协议
DNS占用53号端口,同时使用TCP和UDP协议。
(1)在区域传输的时候使用TCP协议
- 辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。
- TCP是一种可靠连接,保证了数据的准确性。
(2)在域名解析的时候使用UDP协议
- 客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
根域名服务器
用来管辖顶级域(如.com)
, 通常它并不直接把待查询的域名直接转换成IP地址,而是告诉本地域名服务器
下一步应当找哪个顶级域名服务器
进行查询。- 顶级域名服务器:管理在该顶级域名服务器注册的所有二级域名。收到DNS查询请求时,就给出相应的回答,给不出来就找下一级的权限服务器
授权域名服务器
总能将其管辖的主机名
转换为该主机的IP地址
。- 本地域名服务器对域名系统非常重要,一个大学,一个电线联通站点等等。主机发出的DNS查询发给本地域名服务器,再由本地域名服务器代为询问。
在Windows系统中配置“本地连接”
时,就需要填写DNS地址,这个地址就是本地DNS (域名服务器)的地址
DNS完整的查询过程
- 在浏览器的缓存中查找对应的IP地址,如果查找到直接返回,若找不到继续下一步
- 将请求发送给本地DNS服务器(校园网,路由器等),在本地域名服务器缓存中查询,如果找到返回结果,若找不到继续下一步
- 本地DNS服务器向根域名服务器(互联网的主目录)发送请求,根域名服务器会返回一个所查询域的顶级域名服务器地址
- 本地DNS服务器向顶级域名服务器(.top顶级域名)发送请求,接受请求的服务器查询自己的缓存,如果有记录,就返回查询结果,如果没有就返回相关的下一级的权威域名服务器的地址
- 本地DNS服务器向**权限域名服务器(ychch.top)**发送请求,域名服务器返回对应的结果
- 本地DNS服务器将返回结果返回给浏览器,并保存缓存便于下次使用
迭代查询与递归查询
实际上,DNS解析是一个包含迭代查询和递归查询的过程。
- 递归查询指的是查询请求发出后,域名服务器代为向下一级域名服务器发出请求,最后向用户返回查询的最终结果。使用递归 查询,用户只需要发出一次查询请求。
- 迭代查询指的是查询请求后,域名服务器返回单次查询的结果。下一级的查询由用户自己请求。使用迭代查询,用户需要发出 多次的查询请求。
主机
向本地域名服务器
的查询采用的是递归
查询,**本地域名服务器
向根域名服务器
的查询采用迭代
查询**
DNS 记录和报文
DNS 服务器中以资源记录的形式存储信息,每一个 DNS 响应报文一般包含多条资源记录。一条资源记录的具体的格式为(Name,Value,Type,TTL)
四种 Type 的值,分别是 A、NS、CNAME 和 MX :
- 如果 Type = A,则 Name 是主机名,Value 是主机名对应的 IP 地址。因此一条记录为 A 的资源记录,提供了标 准的主机名到 IP 地址的映射。
- 如果 Type = NS,则 Name 是个域名,Value 是负责该域名的 DNS 服务器的主机名。这个记录主要用于 DNS 链式 查询时,返回下一级需要查询的 DNS 服务器的信息。
- 如果 Type = CNAME,则 Name 为别名,Value 为该主机的规范主机名。该条记录用于向查询的主机返回一个主机名 对应的规范主机名,从而告诉查询主机去查询这个主机名的 IP 地址。主机别名主要是为了通过给一些复杂的主机名提供 一个便于记忆的简单的别名。
- 如果 Type = MX,则 Name 为一个邮件服务器的别名,Value 为邮件服务器的规范主机名。它的作用和 CNAME 是一 样的,都是为了解决规范主机名不利于记忆的缺点。
主机记录:
记录类型:
WebSocket
WebSocket是HTML5提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。
WebSocket 的出现就解决了半双工通信的弊端。它最大的特点是:服务器可以向客户端主动推动消息,客户端也可以主动向服务器推送消息。
WebSocket 特点的如下:
- 支持双向通信,实时性更强
- 可以发送文本,也可以发送二进制数据‘’
- 建立在TCP协议之上,服务端的实现比较容易
- 数据格式比较轻量,性能开销小,通信高效
- 没有同源限制,客户端可以与任意服务器通信
- 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
即时通讯的实现:短轮询、长轮询、SSE 和 WebSocket 间的区别?
短轮询的基本思路:
浏览器每隔一段时间向浏览器发送 http 请求,服务器端在收到请求后,不论是否有数据更新,都直接进行响应。这种方式本质上还是浏览器发送请求,服务器接受请求的一个过程,通过让客户端不断的进行请求,使得客户端能够模拟实时地收到服务器端的数据的变化。
这种方式的优点是比较简单,易于理解。缺点是这种方式由于需要不断的建立 http 连接,严重浪费了服务器端和客户端的资源。当用户增加时,服务器端的压力就会变大,这是很不合理的。
长轮询的基本思路:
首先由客户端向服务器发起请求,当服务器收到客户端发来的请求后,服务器端不会直接进行响应,而是先将这个请求挂起,然后判断服务器端数据是否有更新。如果有更新,则进行响应,如果一直没有数据,则到达一定的时间限制才返回。客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
长轮询和短轮询比起来,它的优点是明显减少了很多不必要的 http 请求次数,相比之下节约了资源。
长轮询的缺点在于,连接挂起也会导致资源的浪费。
SSE 的基本思想:
服务器使用流信息向服务器推送信息。严格地说,http 协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明发送的是流信息。也就是说,发送的不是一次性的数据包,而是一个连续不断的数据流。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。
SSE 的方式是单向通信的,只能由服务器端向客户端推送信息
SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 http 协议,目前除了 IE/Edge,其他浏览器都支持。它相对于前面两种方式来说,不需要建立过多的 http 请求,相比之下节约了资源。
WebSocket
是 HTML5 定义的一个新协议,与传统的 http 协议不同,该协议允许由服务器主动的向客户端推送信息。WebSocket 是一个全双工的协议,也就是通信双方是平等的,可以相互发送消息。
使用 WebSocket 协议的缺点是在服务器端的配置比较复杂。
对于这四种即使通信协议,从性能的角度来看:
WebSocket > 长连接(SEE) > 长轮询 > 短轮询
但是,我们如果考虑浏览器的兼容性问题,顺序就恰恰相反了:
短轮询 > 长轮询 > 长连接(SEE) > WebSocket
所以,还是要根据具体的使用场景来判断使用哪种方式。