关于计算机网络:计算机网络

2次阅读

共计 10811 个字符,预计需要花费 28 分钟才能阅读完成。

OSI 七层模型

Open System Interconnection(开放系统互连)

TCP/IP5 层模型

  • 应用层、传输层、网络层、数据链路层、物理层

Http 的几种申请办法是什么?

  • GET 办法:发送一个申请来获得服务器上的资源
  • POST 办法:向 URL 指定的资源提交数据
  • PUT 办法:跟 POST 办法很像,也是向服务器提交数据。put 办法是幂等办法,在申请时容易造成数据冗余。
  • HEAD 办法:只申请页面的首部
  • DELETE 办法:删除服务器上的资源
  • OPTIONS 办法:它用于获取以后 URL 所反对的办法。如果申请胜利,会有一个 Allow 的头蕴含相似“GET,POST”这样的信息
post 与 get 的区别
  1. GET 参数通过 URL 传递,POST 参数放在实体中。
  2. GET 申请在 URL 中传送的参数是有长度限度的,而 POST 没有。(GET 参数裸露在 URL 上,不能用来传递敏感信息)
  3. GET 产生一个 TCP 数据包,header 与 data 一起发。

    POST 产生两个,浏览器先发送 header,等服务器响应后,再发送 data

HTTP 状态码?

  • 2 结尾的示意胜利

    • 个别就是 200
  • 3 结尾的示意重定向

    • 301 永恒重定向
    • 302 长期重定向
  • 4 结尾的示意客户端谬误

    • 403 禁止拜访
    • 404 申请资源不存在
  • 5 结尾的示意服务端谬误

    • 500 执行申请时产生谬误
    • 503 服务器处于超负荷状态或停机保护

301:申请浏览器是会缓存的,例如 http:// 永恒重定向到 https://

302:例如未登陆的用户拜访用户核心会重定向到登录页面,redirect 标识 302。

Cookie 和 Session 的作用以及区别?

Cookie 和 Session 的作用:

客户端和服务器进行交互应用了 HTTP 协定,然而 HTTP 协定是无状态的。然而在有些时候是须要保留一些客户端的申请信息,辨认客户端的某些状态等。就须要用到 Cooike 和 Session 了。

区别
  1. cookie 数据保留在客户端,session 数据保留在服务器端。
  2. cookie 放在他人那,安全性不高。为了晋升安全性,能够在客户端加密,服务端解密。
  3. 当访问量增多时,session 会占用服务器的性能。
  4. 单个 cookie 在客户端的限度是 3k,session 没有大小限度。
  5. cookie 仅反对 ASICC 码,中文须要转化能力传输;session 反对任意格局
  6. 因而,登陆信息等重要信息寄存为 session;其余信息要保留寄存为 cookie。

分布式 session 原理?

  • 分布式 Session 的问题

    客户端发送一个申请,通过 负载平衡 后该申请会被调配到服务器中的其中一个,因为不同服务器有不同的 web 服务器(例如 Tomcat),不同的 web 服务器中并不能发现之前保留的 session 信息,就会再次生成一个 JSESSIONID,之前的状态就会隐没。

  • 解决形式:基于 redis 存储 session 计划
    • 把我的项目中的 session 对立存在 redis 中,所有的参加集群的我的项目都在 redis 中取。
    • spring 为咱们封装好了 spring-session,间接引入依赖即可。

长连贯和短连贯?

  • 在 HTTP/1.0 中默认应用短连贯。即 客户端和服务器每进行一次 HTTP 操作,就建设一次连贯,工作完结后就中断连贯。
  • 而从 HTTP/1.1 起,默认应用长连贯,会在响应头退出这行代码:

    Connection:keep-alive

    在应用长连贯的状况下,当一个网页关上实现后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连贯不会敞开,客户端再次拜访这个服务器时,会持续应用这一条曾经建设的连贯。Keep-Alive 不会永恒放弃连贯,它有一个放弃工夫,可设定。

  • HTTP 协定的长连贯和短连贯,本质上是 TCP 协定的长连贯和短连贯。

HTTP1.0、1.1 和 2.0 的区别?

  • Http0.9 只能进行 get 申请
  • Http1.0 增加了 POST、PUT、DELETE 等申请
  • Http1.1 减少了长连贯 keepAlive、反对断点续传。
  • Http2.0 多路复用、新的二进制格局、头部压缩(防止了反复 header 的传输)

HTTP 和 HTTPS 的区别,https 的实现原理?

区别
  • http 无状态无连贯,而且是明文传输,不平安。
  • https 传输内容加密,身份验证,保障数据完整性。
https 实现原理
  • 首先客户端向服务器发动一个随机值,以及一个加密算法。
  • 服务器收到后返回一个协商好的加密算法,以及另一个随机值
  • 服务器再发送一个公钥 CA
  • 客户端收到当前先验证 CA 是否无效,如果有效则报错弹窗,有过无效则进行下一步操作。
  • 客户端应用之前的两个随机值和一个预主密钥组成一个会话密钥,再通过服务器传来的公钥加密把会话密钥发送给服务器
  • 服务器收到后应用私钥解密,失去两个随机值和预主密钥,而后组装成会话密钥
  • 客户端在向服务器发动一条信息,这条信息应用会话秘钥加密,用来验证服务器能够收到加密的信息。
  • 服务器收到信息后返回一个会话秘钥加密的信息。
  • 都收到当前 SSL 层连贯建设胜利

对称加密、非对称加密优缺点?

  • 对称加密:对称加密算法又称传统加密算法。加密和解密应用同一个密钥。

    • 长处:计算量小,加密速度快,加密效率高
    • 毛病:安全性得不到保障
  • 非对称加密:非对称加密算法须要两个密钥:公开密钥(publickey) 和公有密钥(privatekey),公开密钥和公有密钥是一对。如果用公开密钥对数据进行加密,只有用对应的公有密钥能力解密,反之也是这样。

    • 长处:算法强度简单,安全性高
    • 毛病:加密解密速度慢,只适宜对大量数据进行加密

RSA 利用场景:通常数据自身的加密解密应用对称加密算法,而用 RSA 算法加密并传输对称算法所须要的密钥。

  • CA 证书是什么?

    CA(Certification Authority),证书颁发机构,避免服务器伪造,内含公钥和私钥,应用 CA 公钥进行验证真伪。

DNS 域名解析的流程?

通过 UDP 或者 TCP 传输,个别采纳 UDP

  • 先浏览器缓存,再到 host
  • 本地域名服务
  • 根域名服务器“.”
  • 顶级域名服务器“edu, gov, com, net”
  • 二级域名服务器“baidu, google”

点对点和端对端的区别?

  • 点到点是主机到主机之间的通信。端到端是过程到过程之间的通信。
  • 一台计算机能够与很多台计算机进行通信,应用 IP 对不同的计算机进行辨别(点到点)。
  • 一台计算机上的一个程序(例如 QQ)和很多计算机上的程序通信,须要应用 IP+ 端口 能力惟一的示意一个会话。

深刻了解 TCP 协定:从原理到实战

TCP 概述

一句话形容 TCP 协定:TCP 是一个牢靠的、面向连贯的、基于字节流的、全双工的协定。

  • 面向连贯

    面向连贯的协定要求正式发送数据之前须要通过握手建设一个 逻辑 连贯,完结通信时也是通过有序的四次挥手来断开连接

  • 牢靠的

    IP 是一种无连贯、不牢靠的协定,TCP 想要在 IP 根底上构建牢靠的传输层协定,必须有一个简单的机制来保障。次要有:

    • 对每个包提供校验和
    • 包的序列号解决了接收数据的乱序、反复问题
    • 超时重传
    • 流量管制、拥塞管制

校验和(checksum)每个 TCP 包的首部中都有两字节用来示意校验和,避免在传输过程中有损坏。如果收到一个校验和有过错的保温,TCP 不会发送任何确定间接抛弃它,期待发送端重传。

包的序列号保障了接收数据的乱序和反复问题 假如咱们往 TCP 套接字里写 3000 字节的数据导致 TCP 发送了 3 个数据包,每个数据包大小为 1000 字节。

如果因为网络起因导致第二个、第三个包先到接收端,第一个包最初才到。TCP 会依据他们的序号进行从新的排列而后把后果传递给下层应用程序。

如果 TCP 接管到反复的数据,可能的起因是超时重传了两次但这个包并没有失落,TCP 也可能依据包序号抛弃反复的数据。

超时重传、流量管制、拥塞管制 这部分内容较简单,前面专门讲述。

  • 是面向字节流的

TCP 是一种字节流(byte-stream)协定,流的含意是没有固定的报文边界。

假如你调用 2 次 write 函数往 socket 里一次写 500 字节、800 字节。write 函数只是把字节拷贝到内核缓冲区,最终会以多少条报文发送进来是不确定的,如下图所示

下面呈现的状况取决于诸多因素:门路最大传输单元 MTU、发送窗口大小、拥塞窗口大小等。

  • 是全双工的

在 TCP 中发送端和接收端能够是客户端 / 服务端,也能够是服务端 / 客户端,通信的单方在任意时刻既可接收数据也能够是发送数据。

小结

分析 TCP 首部字段

TCP 头部是撑持 TCP 简单性能的基石。残缺的 TCP 头部如下图所示:

  • 源端口号、指标端口号

TCP 报文头部里没有源 ip 和指标 ip 地址,只有源端口号和指标端口号。因为那是 IP 层协定的事,TCP 层只有源端口和指标端口。

源 IP、源端口、指标 IP、指标端口形成了 TCP 连贯的 四元组。一个四元组能够惟一标识一个连贯。

  • 序列号(Sequence number)

TCP 是面向字节流的协定,通过 TCP 传输的每个字节都调配了序列号,序列号指的是本报文段 第一个字节的序列号。

序列号加上报文的长度,就能够确定传输的是哪一段数据。

因为网络层(IP 层)不保障包的程序,TCP 协定利用序列号来解决网络包乱序、反复的问题,以保障数据表以正确的程序组装传递给下层利用。

初始序列号(Initial Sequence Number, ISN)

在建设连贯之初,通信单方都会各自抉择一个序列号,称之为初始序列号。在建设连贯时,通信单方通过 SYN 报文交换彼此的 ISN。

其中第 2 步和第 3 步能够合并在一起,这就是三次握手的过程。

  • 确认号(Acknowledgment number)

TCP 应用确认号 ACK 来告知对方下一个冀望接管的序列号,小于此确认号的所有字节都曾经收到。

对于 ACK 的几个留神点:

  1. 不是所有的包都须要确认
  2. 不是收到了数据包就要立马确认,能够提早一会再确认
  3. ACK 包自身不须要被确认,否则就会有限循环了
  4. 确认号永远是示意小于此确认号的字节都曾经收到
  • TCP Flags

TCP 有很多种标记,有些用来发动连贯同步初始序列号,有些用来确认数据包,还有些用来完结连贯。

TCP 定义了一个 8 位的字段用来示意 Flags,大部分只用到了后 6 个,如下图所示

咱们通常所说的 SYN、ACK、FIN、RST 其实只是把 flags 对应的 bit 地位为 1 而已,这些标记能够组合应用,比方 SYN+ACK,FIN+ACK 等。

  • 最常见的有上面几个:

    • SYN(synchronized):用于发动连贯数据表同步单方的初始序列号
    • ACK(Acknowledge):确认数据包
    • RST(Reset):这个标记用来强制断开连接
    • FIN(Finish):告诉对方我发完了所有数据,筹备断开连接,前面就不会发数据包给你了。
    • PSH(Push):告知对方这些数据包收到当前应该马上交给下层利用,不能缓存下来。
  • 窗口大小

用于示意窗口大小的“Window Size”只有 16 位,也就是最大窗口是 2^16^=65535 字节(64KB)。

这也太小了,因而 TCP 协定引入了【TCP 窗口缩放】选项作为窗口缩放的比例因子,比例因子的范畴是 0~14,其中最小值 0 示意不缩放。比例因子能够将窗口扩充到原来的 2 的 n 次方。

例如:窗口大小缩放前为 1050,缩放因子为 7,则真正的窗口大小为 1050*2^7^=134400。

  • 可选项

可选项的格局入下所示

例如 MSS,kind=2,length=4,value=1460

罕用的选项有以下几个:

  1. MSS:TCP 容许的从对方接管的最大报文段
  2. SACK:抉择确定选项
  3. Window Scale:窗口缩放选项

MTU 与 MSS

数据传输通过的过程:应用层—> 表示层—> 会话层—> 传输层—> 网络层—> 链路层—> 物理层

  • MSS(Maximum Segment Size)最大报文段长度,工作在网络层。

    MTU(Maximum Transmission Unit)最大传输单元,工作在链路层。

  • IP 数据包长度在超过链路的 MTU 时,发送之前须要分片。而 TCP 层为了 IP 层不必分片被动将包宰割为 MSS 大小。
  • MTU 具备木桶效应。

三次握手

一次经典的三次握手的过程如下图所示:

  • 三次握手的最重要的是替换彼此的 ISN(初始序列号)

SYN 报文不携带数据,然而却占用一个序号,下一次发送时数据序列号要加一。

除了替换彼此的 ISN,三次握手的另一个作用是替换一些辅助信息,比方 MSS、窗口大小、窗口缩放因子、是否反对抉择确认 等。

为什么须要三次握手,两次不行吗?

须要三次握手能力确认单方的接管、发送都是失常的。

三次握手的状态变动

对于客户端而言:

  • 初始的状态是处于 CLOSED 状态。closed 并不是一个实在的状态,而是一个假想的终点和起点。
  • 客户端调用 connect 当前会发送 SYN 同步报文给服务端,进入 SYN-SENT 阶段,客户端将放弃这个阶段晓得收到了服务端的确定包
  • 收到确定包后,它将发送确认服务端 SYN 报文的 ACK 包,同时进入 ESTABLISHED 状态,表明本人曾经筹备好发送数据。

对于服务端而言:

  • 在执行 bind、listen 调用当前进入 LISTEN 状态,期待客户端连贯。
  • 收到客户端的 SYN 同步报文之后,回复确认并发送本人的 SYN 同步报文,这时服务端进入 SYN-RCVD 阶段期待客户端的确认
  • 当收到客户端的确认报文后,进入 ESTABLISHED 状态。这时单方能够相互发数据了。

四次挥手

  1. 客户端调用 close 办法,被动敞开,会发送一个 FIN 报文给服务端,从这以后客户端不能再发送数据了,客户端进入 FIN-WAIT-1 状态。(FIN 报文就是将 FIN 标记位设置为 1)

    • FIN 段是能够携带数据的,比方客户端能够在它最初要发送的数据块中带上 FIN 段。不论 FIN 段是否携带数据,都须要耗费一个序列号。
    • 客户端发送 FIN 包当前不能再发送数据,然而还能够承受服务端发送的数据,这个状态为【半敞开】

      被动发动敞开的一方称为被动敞开方,另一方称为被动敞开方

  2. 服务端收到 FIN 报文后回复确认 ACK 报文给客户端,服务端进入 CLOSE_WAIT,客户端收到 ACK 后进入FIN-WAIT-2 状态。
  3. 服务端也没有数据要发送了,也发一个 FIN 报文给客户端,而后进入 LAST-ACK 状态,期待客户端的确认 ACK。(同后面一样如果 FIN 段没有携带数据,也须要耗费一个序列号)
  4. 客户端收到服务端的 FIN 报文当前,也回复确认 ACK 报文,进入 TIME_WAIT 状态,期待 2 个 MSL 当前进入 CLOSED 状态。

    服务端收到 ACK 后进入 CLOSED 状态。

为什么 FIN 和 SYN 要耗费一个序列号呢?

因为 FIN 和 SYN 信号都是须要 ACK 的,也就是必须回复这个信号,如果它不占用一个字节的话,是判断不出这个 ACK 是回复这个信号 还是回复这个信号之前的数据包的。

例如:如果 FIN 信号不占用一个字节,回复 FIN 的 ACK 包可能被认为是 之前发送的数据包被从新发了一次,第二次挥手无奈实现,连贯也就无奈失常敞开了。

为什么挥手要四次,三次能够吗?

首先,因为有提早确认的存在,是能够把第二部的 ACK 追随第三步的 FIN 包一起发送的。

发送 FIN 包后,会进入半敞开状态,示意本人不会再给对方发数据了。在这种状况下,如果服务端不先立即发送 ACK 示意收到。那可能客户端会因为期待服务端发数据的过程中,重发 FIN 包。

TIME_WAIT 存在的起因?

只有被动断开的那一刚才会进入 TIME_WAIT 状态,且会在那个状态继续 2 个 MSL(Max Segment Lifetime)。

  • 起因:

    1. 数据报文可能会在发送途中提早,因而要等“迷路”的反复报文段在网络中过期生效。否则用 雷同 源端口和指标端口创立新连贯时收到捷足先登的数据包,造成数据错乱。
    2. 确保牢靠实现 TCP 全双工 终止连贯。四次挥手中,最终的 ACK 由被动敞开方收回,如果这个 ACK 失落了,而且不维持 TIME_WAIT 间接进入 CLOSED 状态,则无奈重传 ACK,被动敞开方因而不能及时牢靠的开释。

为什么是 2MSL?

  • 1 个 MSL 确保四次挥手中被动敞开方最初的 ACK 报文最终能达到对端
  • 1 个 MSL 确保对端没有收到 ACK,重传的 FIN 报文能够达到

TCP 的全连贯队列和半连贯队列

  • 半连贯队列,又称 SYN 队列

当服务端调用 listen 函数时,TCP 的状态从 Close 变为 Listen,同时内核创立了这两个队列。

当客户端发动 SYN 到服务器时,服务端收到后发送ACK+SYN,状态变为SYN_RCVD,此时会将这个连贯信息放入 [半连贯队列]。

一旦收到客户端的 ACK,服务端就开始 尝试 把它退出另外一个全连贯队列。

  • 全连贯队列,又称 Accept 队列

[全连贯队列] 蕴含了服务端所有实现了三次握手,然而还未被利用调用 accept 取走的连贯队列。此时的 socket 处于 ESTALISHED 状态。每次利用调用 accept() 会移除队列头的连贯。

如果队列为空,accpet()通常会阻塞。如果全连贯队列满,内核会丢掉客户端发过来的 ACK,连贯就无奈建设。

这个过程有点像生产者消费者模式。内核是一个负责三次握手的生产者,握完手的连贯会放入一个队列。咱们的应用程序是消费者,取走队列中的连贯进行下一步解决。

SYN Flood 攻打

SYN 泛洪攻打是一种 DoS(拒绝服务攻打)。

设想一个场景:客户端大量伪造 IP 发送 SYN 包,服务端回复的 ACK+SYN 去到了一个未知的 IP 地址。会造成服务端大量的连贯处于 SYN_RCVD 状态,而服务器的半连贯队列大小也是有限度的,如果半连贯队列满,也会呈现无奈解决失常申请的状况。

如何应答 SYN Flood 攻打?
  • 减少 SYN 连接数
  • 缩小发送 SYN+ACK 的重试次数
  • SYN Cookie 机制

    • 当初服务器上的 tcp_syncookies 默认等于 1,示意连贯队列满时启用。0 示意禁用、2 示意始终启用。
    • 原理就是:在三次握手的最初阶段才调配连贯资源。

重传机制

  • 永远记住 ACK 是示意这之前的包都曾经全副收到

如果发送 5000 个字节的数据包,因为 MSS 的限度每次传输 1000 个字节,分 5 段传输。

数据包 1 发送的数据失常达到接收端,接收端回复 ACK 1001。如果数据包 2 因为某些起因未能达到服务器,其余包失常达到,这时接收端也不能 ack 3 4 5 数据包,因为数据包 2 还没收到,接收端只能回复 ACK1001。

疾速重传机制与 SACK

疾速重传的含意是:当接收端收到一个不按序达到的数据段时,TCP 立即发送 1 个反复 ACK,当发送端收到 3 个或以上反复 ACK,就意识到之前发的包可能丢了,于是马上进行重传,不必等到重传定时器超时再重传。

这里有一个问题,发送 3、4、5 包收到的全副是 ACK=1001,疾速重传解决了一个问题: 须要重传。因为除了 2 号包,3、4、5 包也可能失落,那到底是只重传 2 号包还是重传 2,3,4,5 所有包呢?

聪慧的网络协议设计者,想到了一个好方法:

  • 收到 3 号包的时候在 ACK 包中通知发送端。我目前收到的最大间断的包序号是 1000(ACK=1001),[1:1001]、[2001:3001] 区间的包我也收到了
  • 收到 4 号包的时候在 ACK 包中通知发送端。我目前收到的最大间断的包序号是 1000(ACK=1001),[1:1001]、[2001:4001] 区间的包我也收到了
  • 收到 5 号包的时候在 ACK 包中通知发送端。我目前收到的最大间断的包序号是 1000(ACK=1001),[1:1001]、[2001:5001] 区间的包我也收到了

这样发送端就分明晓得只用重传 2 号数据包就能够了,数据包 3、4、5 曾经确认无误的被对端收到了。这种形式被称为 SACK(Selective Acknowledgment)

TCP 流量管制(滑动窗口)

TCP 会把要发送的数据放入 发送缓冲区 (Send Buffer),接管到的数据放入 接收缓冲区(Receive Buffer),应用程序会不停的读取接收缓冲区的内容进行解决。

流量管制做的事件就是,如果承受缓冲区已满,发送端应该进行发送数据。

为了管制发送端的速率,接收端会告知客户端本人的接管窗口(rwnd),也就是承受缓冲区中闲暇的局部。

TCP 在收到数据包回复的 ACK 包里会带上本人接管窗口的大小,发送端会依据这个值调整发送策略。

发送窗口和接管窗口

当对方的 ACK 包中表明本人的接管窗口大小后,发送端会把本人的 [发送窗口] 限度在这个大小以内。

如果解决能力无限,导致接收缓冲区满,接管窗口大小为 0,发送端应该进行发送数据。

TCP 包状态分类

从 TCP 角度而言,数据包的状态能够分为四种:

  • 粉色局部 #1:示意已发送并且曾经收到 确认 ACK 的数据包
  • 蓝色局部 #2:示意已发送然而还没收到 确认 ACK 的数据包。如果在一段时间内没有收到 ACK,发送端须要重传这部分数据包。
  • 绿色局部 #3:示意未发送,但接收端有空间能够接管的数据包
  • 黄色局部 #4:示意未发送,而且这部分接收端没有空间接管的数据包

发送窗口(send window)和可用窗口(usable window)

发送窗口 示意在某个时刻,发送端被容许发送的最大数据包大小,包含还没收到确认 ACK 的数据包(#2、#3 区域)

可用窗口 是发送端还能发送的最大数据包大小(#3 区域)

如果上图中的可用窗口的 46~51 发送进来,可用窗口区间减小到 0,这个时候只有收到接收端的 ACK 数据,否则发送端将不能发送数据。

因而,流量管制实际上是对【发送方数据流量】的管制。

拥塞管制

流量管制这种机制的确能够避免发送端向接收端过多的发送数据,然而它只关注了发送端和接收端本身的情况,而没有思考整个网络的通信情况。于是呈现了咱们明天要讲的拥塞解决。

拥塞解决波及上面这几个算法:

  1. 慢启动(Slow Start)
  2. 拥塞防止(Congestion Avoidance)
  3. 疾速重传(Fast Retransmit)和 疾速复原(Fast Recovery)

为了实现下面算法,TCP 的每条连贯都有两个外围值:

  1. 拥塞窗口(Congestion Window,cwnd)
  2. 慢启动阙值(Slow Start Threshold,ssthresh)

拥塞窗口

拥塞窗口(cwnd)和接管窗口(rwnd)有什么区别呢?

  • 接管窗口是 接收端 的限度,是接收端还能接管的数据量大小
  • 拥塞窗口是 发送端 的限度,是发送端在还未收到对端 ACK 之前还能发送的数据量大小

咱们在 TCP 头部的 windows 字段讲的是 接管窗口大小。

拥塞窗口初始值等于操作系统的一个变量 initcwnd,最新的 linux 零碎 initcwnd 默认值等于 10。

  • 真正的发送窗口大小 =【接收端窗口大小】与【发送端本人的拥塞窗口大小】两者的 最小值

如果接管窗口比拥塞窗口小,示意接收端解决能力有余。如果拥塞窗口小于接管窗口,示意接收端有解决能力,但网络拥塞。

因为发送端能发送多少数据,取决于两个因素:

  1. 对方能接管多少(接管窗口)
  2. 本人为了防止网络拥塞被动缩小数据量(拥塞窗口)

发送端和接收端不会替换 拥塞窗口 cwnd 这个值,这个值是保护在发送端本地内存中的一个值

拥塞管制的算法实质是管制拥塞窗口(cwnd)的变动。

拥塞解决算法之:慢启动

拥塞管制是从整个网络的大局观来管制的,如果有足够的带宽,你能够抉择用最快的速度传输数据。然而如果是一个迟缓的挪动网络,发送数据过多,只是造成更大的网络提早。

每个 TCP 连贯都有一个拥塞窗口的限度,最后这个值很小,随着工夫的推移,每次发送的数据量如果在不丢包的状况下,“缓缓”的递增,这种机制被称为【慢启动】

  • 算法过程:

    • 第一步,三次握手当前,单方通过 ACK 通知对方本人接管窗口(rwnd)大小,准备就绪。
    • 第二步,通信单方各自初始化本人的 [拥塞窗口](cwnd)大小
    • 第三步,cwnd 初始值较小时,每收到一个 ACK,cwnd+1;每通过一个 RTT(往返时延),cwnd 变为之前的两倍。

慢启动阙值(Slow Start Threshold,ssthresh)

慢启动算法的拥塞窗口(cwnd)必定不能永无止境的指数级增长上来,它的阙值称为【慢启动阙值】。

  • 当 cwnd < ssthresh 时,拥塞窗口按指数级增长(慢启动)
  • 当 cwnd > ssthresh 时,拥塞窗口按线性增长(拥塞防止)

拥塞解决算法之:拥塞防止(Congestion Avoidance)

当 cwnd > ssthresh 时,拥塞窗口进入「拥塞防止」阶段。

与慢启动的区别在于:每通过一个 RTT 才将拥塞窗口加 1,不论期间收到多少个 ACK。

拥塞解决算法之:疾速复原

后面介绍的慢启动和拥塞防止是 1988 年提出的拥塞管制计划,在 1990 年又呈现了两种新的拥塞管制计划:「疾速重传」和「疾速复原」。疾速重传咱们之前理解过了,当初讲下疾速复原~

  • 当收到三次反复 ACK 时,进入疾速复原阶段。解释为网络轻度拥塞。

    • 拥塞阙值 ssthresh 降为 cwnd 的一半
    • 拥塞窗口 cwnd 设置为 拥塞阙值
    • 拥塞窗口进入线性减少阶段

从浏览器输出 url 后都经验了什么

  • 先进行 DNS 域名解析。先查看本地 hosts 文件,查看有没有以后域名对应的 ip 地址,若有间接发动申请,没有的话会在本地域名服务器去查找,该查找属于递归查找,如果本地域名服务器没查找到,会从根域名服务器查找,该过程属于迭代查找,根域名会通知你从哪个与服务器查找,最初查找到对应的 ip 地址后把对应规定保留到本地的 hosts 文件中。
  • 如果想减速以上及之后的 http 申请过程的话能够应用缓存服务器 CDN,CDN 过程如下:

    • 用户输出 url 地址后,本地 DNS 会解析 url 地址,不过会把最终解析权交给 CNAME 指向的 CDN 的 DNS 服务器
    • CDN 的 DNS 服务器会返回给浏览器一个全局负载平衡 IP
    • 用户会依据全局负载平衡 IP 去申请全局负载平衡服务器
    • 全局负载平衡服务器会依据用户的 IP 地址,url 地址,会通知用户一个区域负载平衡设施,让用户去申请它。
    • 区域负载平衡服务器会为用户抉择一个离用户较近的最优的缓存服务器,并把 ip 地址给到用户
    • 用户想缓存服务器发送申请,如果申请不到想要的资源的话,会一层层向上一级查找,晓得查找到为止。
  • 进行 http 申请,三次握手四次挥手建设断开连接
  • 服务器解决,可能返回 304 也可能返回 200

    • 返回 304 阐明客户端缓存可用,间接应用客户端缓存即可,该过程属于协商缓存
    • 返回 200 的话会同时返回对应的数据
  • 客户端自上而下执行代码

    • 其中遇到 CSS 加载的时候,CSS 不会阻塞 DOM 树的解析,然而会阻塞 DOM 树的渲染,并且 CSS 会阻塞上面的 JS 的执行
    • 而后是 JS 加载,JS 加载会影响 DOM 的解析,之所以会影响,是因为 JS 可能会删除增加节点,如果先解析后加载的话,DOM 树还得从新解析,性能比拟差。如果不想阻塞 DOM 树的解析的话,能够给 script 增加一个 defer 或者 async 的标签。

      • defer:不会阻塞 DOM 解析,等 DOM 解析完之后在运行,在 DOMContentloaed 之前
      • async: 不会阻塞 DOM 解析,等该资源下载实现之后立即运行
    • 进行 DOM 渲染和 Render 树渲染

      • 获取 html 并解析为 Dom 树
      • 解析 css 并造成一个 cssom(css 树)
      • 将 cssom 和 dom 合并成渲染树(render 树)
      • 进行布局(layout)
      • 进行绘制(painting)
      • 回流重绘

        • 回流必将引起重绘,重绘不肯定引起回流
正文完
 0