总结了一些常见的面试题 用于个人复习
时间:2021-10-24
文章目录
- 七层模型各自的作用
- 各层的数据格式
- 一次完整的HTTP请求
- 为什么域名解析用UDP协议
- HTTP长连接和短链接
- TCP粘包 和 粘包发生的原因和解决方案
- 为什么服务器有缓存功能?如何实现?
- HTTP的请求方法
- GET 和 POST的区别
- 一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?
- 浏览器对同一 Host 建立 TCP 连接到的数量有没有限制?
- DNS解析过程(这个写的不错)
- DNS负载均衡是什么策略?
- HTTPS和HTTP的区别
- HTTPS是如何保证数据传输的安全,整体的流程是什么?(SSL是怎么工作保证安全的)
- HTTP请求和响应报文有哪些主要字段?
- Cookie是什么?
- Cookie有什么用途?用途
- Session的工作原理
- Cookie和Session的区别
- SQL注入攻击
- ARP 和 RARP
- 有效端口号
- 为什么把TCP/IP协议分成5层或者7层
- DNS查询方式(递归和迭代)
- POST 方法比 GET 方法安全?
- POST 方法会产生两个 TCP 数据包?你了解吗?
- Session和cookie应该如何去选择(适用场景)?
- DDOS攻击
- TCP头部中有哪些信息?(重要)
- 各层协议
- 三次握手
- 四次握手和二次握手可以吗
- 半连接队列和全连接队列
- SYN攻击(这个很有意思)
- 四次挥手
- 粘包和分包问题
- 流量控制原理(待补充)
- TCP协议如何保证可靠传输(重要)
- TCP和UDP的区别(重要)
- 拥塞避免算法(重要)
七层模型各自的作用
- 物理层:底层数据(比特流)在物理介质的传输
- 数据链路层:帧的封装,进行硬件地址寻址 差错校验
- 网络层:IP寻址和路由选择 协议ICMP IP APR PARP
- 传输层: 端对端的连接 TCP IP
- 会话层: 建立 管理 维护会话
- 表示层:数据格式转化,加密,解密等
- 应用层:为应用程序提供服务:协议有HTTP FTP DNS…
网络七层模型是一个标准,而非实现。 网络四层模型是一个实现的应用模型。 网络四层模型由七层模型简化合并而来。
各层的数据格式
- 在四层,既传输层数据被称作段(Segments);
- 三层网络层数据被称做包(Packages);
- 二层数据链路层时数据被称为帧(Frames);
- 一层物理层时数据被称为比特流(Bits)。
一次完整的HTTP请求
- 域名解析
- 发起TCP的3次握手
- 建立TCP连接后发起http请求
- 服务器响应http请求,浏览器得到html代码
- 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
- 浏览器对页面进行渲染呈现给用户。
为什么域名解析用UDP协议
- DNS: 将主机域名转换为ip地址,属于应用层协议,使用UDP传输。
-
UDP的DNS协议只要一个请求、一个应答就好了。快
-
而使用基于TCP的DNS协议要三次握手、发送数据以及应答、四次挥手,但是UDP协议传输内容不能超过512字节。
-
不过客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。
HTTP长连接和短链接
-
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
-
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。
TCP粘包 和 粘包发生的原因和解决方案
-
应用程序写入的数据大于套接字缓冲区大小,这将会发生拆包。
-
应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包。
-
进行mss(最大报文长度)大小的TCP分段,当TCP报文长度-TCP头部长度>mss的时候将发生拆包。
-
接收方法不及时读取套接字缓冲区数据,这将发生粘包。
解决方案
-
1消息定长。
-
2在包尾部增加回车或者空格符等特殊字符进行分割
-
3 将消息分为消息头和消息尾。
-
4 使用其它复杂的协议,如RTMP协议等。
为什么服务器有缓存功能?如何实现?
原因
- 缓解服务器压力;
- 降低客户端获取资源的延迟:缓存通常位于内存中,读取缓存的速度更快。并且缓存服务器在地理位置上也有可能比源服务器来得近,例如浏览器缓存。
实现方法
- 让代理服务器进行缓存;
- 让客户端浏览器进行缓存。
HTTP的请求方法
- HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
- HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
GET 和 POST的区别
- get是获取数据,post是修改数据
- get把请求的数据放在url上,
以?分割URL和传输数据,参数之间以&相连,所以get不太安全。而post把数据放在HTTP的包体内(requrest body) - get提交的数据最大是2k( 限制实际上取决于浏览器), post理论上没有限制。
- GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200
ok(返回数据)。 - GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
- 本质区别:GET是幂等的,而POST不是幂等的
一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?
HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。
在 HTTP/1.1 存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。在 HTTP2 中由于 Multiplexing 特点的存在,多个 HTTP 请求可以在同一个 TCP 连接中并行进行。
那么在 HTTP/1.1 时代,浏览器是如何提高页面加载效率的呢?主要有下面两点:
- 维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。
- 和服务器建立多个 TCP 连接。
浏览器对同一 Host 建立 TCP 连接到的数量有没有限制?
DNS解析过程(这个写的不错)
- 请求一旦发起,若是chrome浏览器,先
在浏览器找之前有没有缓存过的域名所对应的ip地址
,有的话,直接跳过dns解析了,若是没有,就会找硬盘的hosts文件
,看看有没有,有的话,直接找到hosts文件里面的ip - 如果本地的hosts文件没有能得到对应的ip地址,
浏览器会发出一个dns请求到本地dns服务器,
本地dns服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动等。 - 查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,
本地DNS服务器还要向DNS根服务器进行查询
。 - 本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。
- 最后
,本地DNS服务器向域名的解析服务器发出请求
,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
DNS负载均衡是什么策略?
当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会蹦掉。处理办法就是用DNS负载均衡技术,它的原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器
,从而达到负载均衡的目的。例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。
HTTPS和HTTP的区别
- HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全, HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
- https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
SSL代表安全套接字层。它是一种用于加密和验证应用程序(如浏览器)和Web服务器之间发送的数据的协议。 身份验证 , 加密Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。
HTTPS是如何保证数据传输的安全,整体的流程是什么?(SSL是怎么工作保证安全的)
(1)客户端向服务器端发起SSL连接请求;
(2) 服务器把公钥发送给客户端,并且服务器端保存着唯一的私钥
(3)客户端用公钥对双方通信的对称秘钥进行加密,并发送给服务器端
(4)服务器利用自己唯一的私钥对客户端发来的对称秘钥进行解密,
(5)进行数据传输,服务器和客户端双方用公有的相同的对称秘钥对数据进行加密解密,可以保证在数据收发过程中的安全,即是第三方获得数据包,也无法对其进行加密,解密和篡改。
- 简便回答
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
HTTP请求和响应报文有哪些主要字段?
请求
- 请求行:Request Line
- 请求头:Request Headers
- 请求体:Request Body
响应
- 状态行:Status Line
- 响应头:Response Headers
- 响应体:Response Body
Cookie是什么?
HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务,HTTP/1.1 引入 Cookie 来保存状态信息。
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据
,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销
cookie 的出现是因为 HTTP 是无状态的一种协议,换句话说,服务器记不住你,可能你每刷新一次网页,就要重新输入一次账号密码进行登录。这显然是让人无法接受的,cookie 的作用就好比服务器给你贴个标签,然后你每次向服务器再发请求时,服务器就能够 cookie 认出你。
抽象地概括一下:一个 cookie 可以认为是一个「变量」,形如 name=value,存储在浏览器;一个 session 可以理解为一种数据结构,多数情况是「映射」(键值对),存储在服务器上。
Cookie有什么用途?用途
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
Session的工作原理
session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。
用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
服务器验证该用户名和密码,如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;
客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。
Cookie和Session的区别
Cookie和Session都是客户端与服务器之间保持状态的解决方案 1,存储的位置不同,cookie:存放在客户端,session:存放在服务端。Session存储的数据比较安全 2,存储的数据类型不同 两者都是key-value的结构,但针对value的类型是有差异的 cookie:value只能是字符串类型,session:value是Object类型 3,存储的数据大小限制不同 cookie:大小受浏览器的限制,很多是是4K的大小, session:理论上受当前内存的限制, 4,生命周期的控制 cookie的生命周期当浏览器关闭的时候,就消亡了 (1)cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束, (2)session的生命周期是间隔的,从创建时,开始计时如在20分钟,没有访问session,那么session生命周期被销毁
SQL注入攻击
攻击者在HTTP请求中注入恶意的SQL代码,服务器使用参数构建数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。 用户登录,输入用户名 lianggzone,密码 ‘ or ‘1’=’1 ,如果此时使用参数构造的方式,就会出现 select * from user where name = ‘lianggzone’ and password = ‘’ or ‘1’=‘1’ 不管用户名和密码是什么内容,使查询出来的用户列表不为空。如何防范SQL注入攻击使用预编译的PrepareStatement是必须的,但是一般我们会从两个方面同时入手。 Web端 1)有效性检验。 2)限制字符串输入的长度。 服务端 1)不用拼接SQL字符串。 2)使用预编译的PrepareStatement。 3)有效性检验。(为什么服务端还要做有效性检验?第一准则,外部都是不可信的,防止攻击者绕过Web端请求) 4)过滤SQL需要的参数中的特殊字符。比如单引号、双引号。
ARP 和 RARP
- 简单的说 ARP 知道源IP 源MAC 目的IP 求目的MAC地址
- RARP是不知道源IP 知道其他三个
有效端口号
-
0-1023为知名端口号,比如其中HTTP是80,FTP是20(数据端口)、21(控制端口)
-
UDP和TCP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。动态端口的范围是从1024到65535
为什么把TCP/IP协议分成5层或者7层
-
①隔层之间是独立的。
-
②灵活性好。
-
③结构上可以分隔开
-
④易于实现和维护。
-
⑤能促进标准化工作。
DNS查询方式(递归和迭代)
-
当局部DNS服务器自己不能回答客户机的DNS查询时,它就需要向其他DNS服务器进行查询。此时有两种方式。
局部DNS服务器自己负责向其他DNS服务器进行查询,一般是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询
。最后得到的查询结果返回给局部DNS服务器,再由局部DNS服务器返回给客户端
。 -
当局部DNS服务器自己不能回答客户机的DNS查询时,也可以通过迭代查询的方式进行解析。
局部DNS服务器不是自己向其他DNS服务器进行查询,而是把能解析该域名的其他DNS服务器的IP地址返回给客户端DNS程序,客户端DNS程序再继续向这些DNS服务器进行查询,直到得到查询结果为止。
也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。比如说:baidu.com的服务器ip地址在192.168.4.5这里,你自己去查吧,本人比较忙,只能帮你到这里了。
POST 方法比 GET 方法安全?
有人说POST 比 GET 安全,因为数据在地址栏上不可见。
然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS。
POST 方法会产生两个 TCP 数据包?你了解吗?
有些文章中提到,POST 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。
HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和 body 不会分开发送。
所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。
Session和cookie应该如何去选择(适用场景)?
- Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session;
- Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
- 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。
DDOS攻击
客户端向服务端发送请求链接数据包,服务端向客户端发送确认数据包,客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认 没有彻底根治的办法,除非不使用TCP DDos 预防: 1)限制同时打开SYN半链接的数目 2)缩短SYN半链接的Time out 时间 3)关闭不必要的服务
TCP头部中有哪些信息?(重要)
-
序号(32bit):传输方向上字节流的字节编号。初始时序号会被设置一个随机的初始值(ISN),之后每次发送数据时,序号值 = ISN + 数据在整个字节流中的偏移。假设A -> B且ISN = 1024,第一段数据512字节已经到B,则第二段数据发送时序号为1024 + 512。用于解决网络包乱序问题。
-
确认号(32bit):接收方对发送方TCP报文段的响应,其值是收到的序号值 + 1。
-
首部长(4bit):标识首部有多少个4字节 * 首部长,最大为15,即60字节。
-
标志位(6bit):
-
URG:标志紧急指针是否有效。
-
ACK:标志确认号是否有效(确认报文段)。用于解决丢包问题。
-
PSH:提示接收端立即从缓冲读走数据。
-
RST:表示要求对方重新建立连接(复位报文段)。
-
SYN:表示请求建立一个连接(连接报文段)。
-
FIN:表示关闭连接(断开报文段)。
-
-
窗口(16bit):接收窗口。用于告知对方(发送方)本方的缓冲还能接收多少字节数据。用于解决流控。
-
校验和(16bit):接收端用CRC检验整个报文段有无损坏。
各层协议
三次握手
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态,进行三次握手:
- 第一次握手:客户端向服务端发送一个SYN报文,包括一个随机初始化的序列号seq=x,
- 第二次握手:服务端收到SYN报文,以自己SYN报文作为应答,在确认报文段中SYN=1 ACK=1 初始序列号seq=y,确认序列号 ack=x+1(就是期待确认 就是希望下次你发来的包序号)
- 第三次握手:发送ACK应答,确认报文段ACK=1,确认号ack=y+1,序号seq=x+1。
这个时候可以携带数据 不携带数据则不消耗序号
补充:ACK SYN FIN这些都是控制信息 不算实际信息
四次握手和二次握手可以吗
- 这个没啥好说的 在之前博客写过了
半连接队列和全连接队列
- 之前博客写过了
SYN攻击(这个很有意思)
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
常见的防御 SYN 攻击的方法有如下几种:
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies技术
四次挥手
-
建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务器均可主动发起挥手动作。
-
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。 即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
-
第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。 即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
服务器告诉客户端说我知道你不给我发信息了 但是你等等 我待会还有没发完的
-
第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。 即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
-
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。 即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
这个时候TIME_WAIT就是看看服务器会不会再发起请求(表示没收到我的应答),如果时间内没有任何动静了 那就彻底结束了
收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。在socket编程中,任何一方执行close()操作即可产生挥手操作。
粘包和分包问题
-
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
-
分包:传输数据不完整,一条信息被分成多次发送
-
粘包:就是多条数据粘在一起
-
或者说数据太长大于套接字发送缓冲区的大小
送端需要等发送缓冲区满才发送出去,造成粘包
接收方不及时接收缓冲区的包,造成多个包接收
换种说法:
- 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
- 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
- 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。
解决方案 - 尾部标记序列。通过特殊标识符表示数据包的边界,例如\n\r,\t,或者一些隐藏字符。
- 头部标记分步接收。在TCP报文的头部加上表示数据长度。(分成包头和包体)
- 应用层发送数据时定长发送。
流量控制原理(待补充)
TCP协议如何保证可靠传输(重要)
TCP和UDP的区别(重要)
- 所以 视频通话 这种都是UDP
- 文件传输 登入校验为TCP保证可靠
拥塞避免算法(重要)
慢热启动算法 – Slow Start
-
所谓慢启动,也就是TCP连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。
-
步骤(简单记忆:
从1开始指数增长 大于慢开始门限 进入拥塞避免算法
)- 连接建好的开始先初始化拥塞窗口cwnd大小为1,表明可以传一个MSS大小的数据。
- 每当收到一个ACK,cwnd大小加一,呈线性上升。
- 每当过了一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接翻倍,乘以2,呈指数让升。
- 还有一个ssthresh(slow start threshold (慢开始门限),当cwnd >= ssthresh时,就会进入“拥塞避免算法”。
-
拥塞避免算法
加法增长
:每当一个往返之间RTT,拥塞窗口+1,即让窗口缓慢增大,按照线性规律增长。乘法减少
:当出现网络拥塞,比如丢包,将慢开始门限(ssthresh)设为当前拥塞窗口cwnd的一半。并且将cmnd设为一,执行慢开始算法。(1是减半 2而是从cwnd1开始 3进入慢启动)
- 最为早期的TCP Tahoe算法就只使用上述处理办法,但是由于一丢包就一切重来,导致cwnd又重置为1,
十分不利于网络数据的稳定传递。
- 所以,TCP Reno算法进行了优化。
当收到三个重复确认ACK时,TCP开启快速重传Fast Retransmit算法,而不用等到
RTO超时再进行重传:
- 快重传和快恢复
- 接收方如果丢失一个包,则对后续的包进行发送针对该包的重传请求。
- 一旦发送方收到三个一样的确认(连续4个相同的ACK,标志一个数据段丢失),就知道该包之后出现错误,立刻重传改包。
- 此时发送方开始执行“快恢复算法”
- 慢开始门限减半
- cwnd为满开是门限减半后的数值
- 执行拥塞避免算法(高起点,线性增长)。