【面试】一文总结最高频HTTP/HTTPS/TCP/UDP面试题

 

目录

HTTP和HTTPS的区别

HTTP1.0/1.1/2.0的区别

无状态协议

GET和POST区别

UDP和TCP的区别

三次握手和四次挥手

HTTP常见的请求头

地址栏输入URL发生了什么

常见状态码

TCP保证有效传输

重传机制

滑动窗口

流量控制

拥塞控制


HTTP和HTTPS的区别

HTTP

HTTP(Hypertext Transfer Protocol secure)是一种超文本传输协议,主要内容分为三个部分,超文本、传输、协议。

  • 超文本不仅仅是文本,还可以是传输图片、音频、视频等
  • 上面这些可以统称为数据,传输就是经过一系列的物理截止从一个端系统传送到另一个端系统的过程。通常我们把传输数据包的一方称为请求方,把接收到二进制数据包的一方称为应答方。
  • 协议指的是网络中传递、管理信息的一些规范。计算机之间相互通信需要共同遵守一定的规则

TCP/IP网络模型,一般是五层模型。如下图所示

 

HTTPS

HTTPS比HTTP多了secure概念,Hypertext Transfer Protocol Secure。 在HTTP的基础上增加了SSL/TLS协议组合而成,HTTPS就是批了一层SSL的HTTP。

HTTP和HTTPS的主要区别

  • 最简单的是HTTP地址栏的协议是以http://开头,而HTTPS是以https://开头
  • HTTP的默认端口是80,HTTPS默认端口是443
  • HTTP是未经安全加密的协议,传输过程容易被攻击者监听、数据容易被窃取,发送方和接收方容易被伪造;HTTPS是安全的协议,通过密钥交换算法、签名算法、对称加密算法、摘要算法能够解决HTTP的安全问题。

 

SSL/TLS四次握手过程

1、 客户端发出请求

首先,客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。

2、服务器回应

服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。生成随机数1,返回数字证书和公钥

3、客户端回应

客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。然后使用公钥加密生成一个随机数2,返回给服务器

4、服务器的最后回应

服务器用私钥解密随机数2,生成随机数3。然后用三个随机数生成“对话密钥”,并返回给客户端。

 

(1) SSLclient通过Client Hello消息将它支持的SSL版本号、加密算法、密钥交换算法、MAC算法等信息发送给SSLserver。

(2) SSLserver确定本次通信采用的SSL版本号和加密套件,并通过Server Hello消息通知给SSLclient。假设SSLserver同意SSLclient在以后的通信中重用本次会话,则SSLserver会为本次会话分配会话ID。并通过Server Hello消息发送给SSLclient。

(3) SSLserver将携带自己公钥信息的数字证书通过Certificate消息发送给SSLclient。

(4) SSLserver发送Server Hello Done消息。通知SSLclient版本号和加密套件协商结束。开始进行密钥交换。

(5) SSLclient验证SSLserver的证书合法后,利用证书中的公钥加密SSLclient随机生成的premaster secret,并通过Client Key Exchange消息发送给SSLserver。

(6) SSLclient发送Change Cipher Spec消息,通知SSLserver兴许报文将采用协商好的密钥和加密套件进行加密和MAC计算。

(7) SSLclient计算已交互的握手消息(除Change Cipher Spec消息外全部已交互的消息)的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并加入MAC值、加密等),并通过Finished消息发送给SSLserver。SSLserver利用相同的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,假设二者相同,且MAC值验证成功,则证明密钥和加密套件协商成功。

(8) 相同地。SSLserver发送Change Cipher Spec消息,通知SSLclient兴许报文将采用协商好的密钥和加密套件进行加密和MAC计算。

(9) SSLserver计算已交互的握手消息的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并加入MAC值、加密等),并通过Finished消息发送给SSLclient。SSLclient利用相同的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,假设二者相同。且MAC值验证成功。则证明密钥和加密套件协商成功。

SSLclient接收到SSLserver发送的Finished消息后。假设解密成功,则能够推断SSLserver是数字证书的拥有者,即SSLserver身份验证成功,由于仅仅有拥有私钥的SSLserver从Client Key Exchange消息中解密得到premaster secret,从而间接地实现了SSLclient对SSLserver的身份验证。

说明:

* Change Cipher Spec消息属于SSLpassword变化协议,其它握手过程交互的消息均属于SSL握手协议,统称为SSL握手消息。

* 计算Hash值。指的是利用Hash算法(MD5或SHA)将随意长度的数据转换为固定长度的数据。

 

HTTP1.0/1.1/2.0的区别

HTTP1.0

  • HTTP 1.0 仅仅提供了最基本的认证,这时候用户名和密码还未经加密,因此很容易收到窥探。
  • HTTP 1.0 被设计用来使用短链接,即每次发送数据都会经过 TCP 的三次握手和四次挥手,效率比较低。
  • HTTP 1.0 只使用 header 中的 If-Modified-Since 和 Expires 作为缓存失效的标准。
  • HTTP 1.0 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
  • HTTP 1.0 认为每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名(hostname)。

HTTP1.1

  • HTTP 1.1 使用了摘要算法来进行身份验证
  • HTTP 1.1 默认使用长连接,长连接就是只需一次建立就可以传输多次数据,传输完成后,只需要一次切断连接即可。长连接的连接时长可以通过请求头中的 keep-alive 来设置
  • HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效。
  • HTTP 1.1 支持断点续传,通过使用请求头中的 Range 来实现。
  • HTTP 1.1 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。

HTTP2.0

  • 头部压缩,由于 HTTP 1.1 经常会出现 User-Agent、Cookie、Accept、Server、Range 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法进行压缩。
  • 二进制格式,HTTP 2.0 使用了更加靠近 TCP/IP 的二进制格式,而抛弃了 ASCII 码,提升了解析效率
  • 强化安全,由于安全已经成为重中之重,所以 HTTP2.0 一般都跑在 HTTPS 上。
  • 多路复用,即每一个请求都是是用作连接共享。一个请求对应一个id,这样一个连接上可以有多个请求。

 

无状态协议

无状态协议就是指浏览器对于事务的处理没有记忆能力。HTTP就是一种无状态的协议,他对用户的操作没有记忆能力。

为什么我在网站输入一次用户名和密码后,下次登录可以不用重新输入呢?

这是基于cookie机制(TCP快速建立连接原理),它让浏览器有了记忆能力。

 

客户端向服务端发送请求的时候,服务端会给你发送一个认证信息,服务器第一次接收到请求的时候,开辟一块session空间,同时生成一个sessionid,并通过响应头的Set-Cookie,返回给客户端。客户端收到响应后,设置自己的Cookie,以后请求就可以带着Cookie访问,浏览器通过拿到cookie生成sessionid就可以鉴定客户端的身份。所以浏览器就有了记忆能力。

JWT-Token机制

JWT和Cookie不同,JWT是保存在客户端的信息,它适用于单点登录的情况。

  • JWT的Token信息存储在客户端,而不是在服务器的内存中,或许数据库中。性能更好,响应更快。
  • JWT可以支持跨域认证,cookie一般只在单个节点的域或者子域中。无法通过第三方的节点访问,JWT可以有效解决这个问题。更适用于移动端
  • 不再依赖cookie,不需要考虑csrf的防范。

Token机制

1. 客户端使用用户名跟密码请求登录

2. 服务端收到请求,去验证用户名与密码

3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端

4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里

5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token

6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向

客户端返回请求的数据

 

GET和POST区别

HTTP包含许多方法,GET和POST是HTTP中最常用的两个方法

  • get方法一般用于请求,它的主要特征是请求服务器返回资源,post一般用于表单的提交,相当于是把信息提交给服务器,等待服务器做出相应反应。get相当于pull/拉,post相当于push/推的操作。
  • get方法是不安全的,因为在发送请求的时候,请求参数会拼接在URL后面,容易被人窃取,对你的信息造成破坏和伪造。post是将请求放在body中,对用户是不可见的。
  • get请求URL长度有限制,post由于把请求参数放在消息体中,没有长度限制。
  • get会被浏览器主动缓存,post不会,除非手动设置。
  • get在 回退/前进 操作是无害的,post会再次提交表单。
  • get请求会在发送过程中产生一个TCP数据包;post在发送过程中会产生两个TCP数据包。对于get请求方式,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于post,浏览器先发送header,服务器响应100,浏览器再发送data,服务器响应200.

 

UDP和TCP的区别

TCP和UDP都是位于计算机网络中的运输层,它们负责传输应用层产生的数据。

UDP

UDP不需要所谓的握手操作,从而加快了通信速度,允许网络上的其他主机在接收方同意通信之前进行数据传输。

  • UDP 能够支持容忍数据包丢失的带宽密集型应用程序
  • UDP 低延迟
  • UDP 能够发送大量的数据包
  • 能够允许DNS查找,DNS是建立在UDP之上的应用层协议

TCP

在传输之前会进行三次握手确认连接

  • TCP 能够保证连接的建立和数据包的发送
  • TCP 支持错误重传机制
  • TCP 支持拥塞控制,能够在网络拥堵的情况下延迟发送
  • TCP 能够提供错误校验和,甄别有害的数据包

UDP和TCP的不同点

  • UDP是无连接的,即发送数据之前不需要建立连接。TCP面向连接
  • UDP使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制。TCP提供可靠服务,保证传输数据无差错、不丢失、不重复,按序到达,提供全双工信道
  • UDP是面向报文的,没有拥塞控制,适合多媒体通信要求。TCP面向字节流,适用于邮件、FTP、SSH等
  • UDP支持一对一,一对多,多对一和多对多的交互通信。TCP只能一对一
  • UDP首部开销小,只有8个字节,TCP首部20个字节

 

三次握手和四次挥手

三次握手和四次挥手,分别对应了TCP的连接和释放过程。

先了解几个概念

三次握手

第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

 

小明 - 客户端 小红 - 服务端

  • 小明给小红打电话,接通了后,小明说喂,能听到吗,这就相当于是连接建立。
  • 小红给小明回应,能听到,你能听到我说的话吗,这就相当于是请求响应。
  • 小明听到小红的回应后,好的,这相当于是连接确认。在这之后小明和小红就可以通话/交换信息了。

 

四次挥手

  • 第一次挥手:客户端应用程序决定要终止连接(这里服务端也可以选择断开连接)。这会使客户端将 FIN 发送到服务器,并进入 FIN_WAIT_1 状态。当客户端处于 FIN_WAIT_1 (终止等待1)状态时,它会等待来自服务器的 ACK 响应。
  • 第二次挥手:当服务器收到 FIN 消息时,服务器(CLOSE-WAIT 关闭等待)会立刻向客户端发送 ACK 确认消息。当客户端收到服务器发送的 ACK 响应后,客户端就进入 FIN_WAIT_2 (终止等待2)状态,然后等待来自服务器的 FIN 消息。
  • 服务器发送 ACK 确认消息后(LAST-ACK状态 最后确认),一段时间(可以进行关闭后)会发送 FIN 消息给客户端,告知客户端可以进行关闭。在一次使用wireshark抓包验证过程中,只有三次挥手。原因是因为接收到client的终止连接请求后,服务端并没有未发送完的数据。这时候第二次和第三次挥手在一个包中进行发送。
  • 当客户端收到从服务端发送的 FIN 消息时,客户端就会由 FIN_WAIT_2 状态变为 TIME_WAIT (时间等待)状态。处于 TIME_WAIT 状态的客户端允许重新发送 ACK 到服务器为了防止信息丢失。客户端在 TIME_WAIT 状态下花费的时间取决于它的实现,在等待2MSL时间后,连接关闭,客户端上所有的资源(包括端口号和缓冲区数据)都被释放。

 

还是可以用上面那个通话的例子来进行描述

  • 小明对小红说,我所有的东西都说完了,我要挂电话了。
  • 小红说,收到,我这边还有一些东西没说。
  • 经过若干秒后,小红也说完了,小红说,我说完了,现在可以挂断了
  • 小明收到消息后,又等了若干时间后,挂断了电话。

常见问题

为什么TIME_WAIT需要经过2MSL才能返回到CLOSE状态?

虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

如果已经建立了连接,客户端出现了故障怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

为什么是三次握手,不是二次或者四次握手?

TCP是全双工的,即客户端在给服务器端发送信息的同时,服务器端也可以给客户端发送信息。所以就需要确定,客户端和服务端需要确认自己和对方都具有良好的收发能力。

第一次握手:A对B 说,你可以听到我说话吗?

第二次握手:B回A的消息,我能听到你说话,你能听到我说话吗?这个阶段B知道A的发送能力,自己的接收能力。

第三次握手:A收到B的信息,说可以听到你说话。A知道自己的接收和发送能力都是好的,B的接收和发送能力是正常的。B此时知道了自己的发送能力正常,A的接收能力正常。

 

HTTP常见的请求头

HTTP标头会分为四种,分别是通用标头、实体标头、请求标头、响应标头。

通用标头

Date: 日期时间

Cache-Control:缓存控制

Connection:持久性连接/非持久性连接

实体标头

实体标头是描述消息正文内容的HTTP标头。实体标头用于HTTP请求和响应中

Content-Length:实体主题的大小,以字节为单位,发送到接收方

Content-Language:描述了客户端或者服务端能够接受的语言

Content-Encoding:压缩媒体类型,采用何种编码

请求标头

Host:指明了服务器的域名,以及可选的端口号(默认为80)

Refer:告诉服务器是从哪个页面链接过来的

If-Modified-Since:如果在Last-Modified之后更新了服务器资源,那么服务器会响应200,如果Last-Modified之后没有更新过资源,则返回304.

Accept: 接受请求HTTP表土会告知客户端其能够理解的MIME类型

Accept-Charset: 服务器处理表单数据接受的字符集

Accept-Language:服务器能够处理的自然语言集

响应标头

keep-alive:非持续连接的存活时间,可以进行指定

server:服务器标头包含有关原始服务器用来处理请求的软件的信息

Set-Cookie:用于服务器向客户端发送sessionID

Transfer-Encoding:首部字段Transfer-Encoding规定了传输报文主题时采用的编码方式

地址栏输入URL发生了什么

  1. 域名解析
    1. 浏览器查看自己的DNS缓存
    2. 操作系统的DNS缓存
    3. 操作系统的host文件
    4. 本地DNS服务器
    5. 根域名服务器-->顶级域名服务器-->权威DNS服务器-->告知本地服务器目标IP地址
  2. 三次握手
  3. 建立连接后发送HTTP请求
  4. 服务器接收到请求并响应请求
  5. 浏览器解析htm代码,请求代码中的资源
  6. 四次挥手断开TCP连接
  7. 浏览器对页面渲染呈现

常见状态码

1xx

1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。

2xx

2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。

「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。

「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。

「206 Partial Content」是应用于 HTTP 分块下载或断电续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。

3xx

3xx 类状态码表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。

「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。

「302 Moved Permanently」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。

301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。

4xx

4xx 类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。

「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。

「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。

「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

5xx

5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。

「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。

「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。

「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。

「503 Service Unavailable」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

 

TCP保证有效传输

重传机制

TCP如果在传输过程中,数据丢失了怎么办?针对TCP丢包情况,会用重传机制解决。常见的重传机制:

  • 超时重传
  • 快速重传
  • SACK
  • D-SACK

超时重传

发送数据的时候,设定一个定时器,如果超过指定的时间没有接收到对方的ACK确认应答报文,就会重发该数据。

两种情况下回发送超时重传:

  • 数据包丢失
  • 确认应答丢失

超时重传时间RTO:

  • RTO过大,重发就慢,丢了老半天才会重发,效率低,性能差
  • RTO过小,可能导致没有丢就重发,重发的快,会增加网络拥塞,导致更多的超时,更多超时导致更多的重发...

超时重传时间RTO的值应该略大于报文往返RTT的值。(RTT包的往返时间)。RTT的值是多次测试得到的一个靠谱的值。

超时重发的数据,再次超时的时候,又需要重传的时候,TCP策略是超时间隔加倍。两次超时,就说明网络环境差,不宜频繁反复发送。

超时重传的存在的问题是,超时周期可能相对较长。是不是有可以有更快的方式呢?【快速重传】

 

快速重传

TCP还有另外一种快速重传机制,不以时间为驱动,而是以数据驱动重传。

 

在上图,发送方发出了 1,2,3,4,5 份数据:

  • 第一份 Seq1 先送到了,于是就 Ack 回 2;
  • 结果 Seq2 因为某些原因没收到,Seq3 到达了,于是还是 Ack 回 2;
  • 后面的 Seq4 和 Seq5 都到了,但还是 Ack 回 2,因为 Seq2 还是没有收到;
  • 发送端收到了三个 Ack = 2 的确认,知道了 Seq2 还没有收到,就会在定时器过期之前,重传丢失的 Seq2。
  • 最后,接收到收到了 Seq2,此时因为 Seq3,Seq4,Seq5 都收到了,于是 Ack 回 6 。

所以,快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。

快速重传机制只解决了一个问题,就是超时时间的问题,但是它依然面临着另外一个问题。就是重传的时候,是重传之前的一个,还是重传所有的问题。

比如对于上面的例子,是重传 Seq2 呢?还是重传 Seq2、Seq3、Seq4、Seq5 呢?因为发送端并不清楚这连续的三个 Ack 2 是谁传回来的。

SACK

这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将缓存的地图发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据

D-SACK

Duplicate SACK 又称 D-SACK,其主要使用了 SACK 来告诉「发送方」有哪些数据被重复接收了。

 

滑动窗口

引入滑动窗口的原因

TCP每发送一个数据包,都要进行一次确认应答,当上一个数据包接受到了应答,再发送下一个。

这个模式就有点像我和你面对面聊天,你一句我一句。但这种方式的缺点是效率比较低的。

如果你说完一句话,我在处理其他事情,没有及时回复你,那你不是要干等着我做完其他事情后,我回复你,你才能说下一句话,很显然这不现实。

所以,这样的传输方式有一个缺点:数据包的往返时间越长,通信的效率就越低。

 

为解决这个问题,TCP 引入了窗口这个概念。即使在往返时间较长的情况下,它也不会降低网络通信的效率。

那么有了窗口,就可以指定窗口大小,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值

窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。

图中的 ACK 600 确认应答报文丢失,也没关系,因为可以通话下一个确认应答进行确认,只要发送方收到了 ACK 700 确认应答,就意味着 700 之前的所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答

窗口大小由谁决定的?

TCP 头里有一个字段叫 Window,也就是窗口大小。

这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。

所以,通常窗口的大小是由接收方的决定的。

发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。

 

流量控制

发送方不能无脑的发数据给接收方,要考虑接收方处理能力。

如果一直无脑的发数据给对方,但对方处理不过来,那么就会导致触发重发机制,从而导致网络流量的无端的浪费。

为了解决这种现象发生,TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。

 

拥塞控制

为什么要有拥塞控制?

流量控制是避免「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么。

一般来说,计算机网络都处在一个共享的环境。因此也有可能会因为其他主机之间的通信使得网络拥堵。

在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大….

 

所以,TCP 不能忽略网络上发生的事,它被设计成一个无私的协议,当网络发送拥塞时,TCP 会自我牺牲,降低发送的数据量。

于是,就有了拥塞控制,控制的目的就是避免「发送方」的数据填满整个网络

为了在「发送方」调节所要发送数据的量,定义了一个叫做「拥塞窗口」的概念。

什么是拥塞窗口?

cwnd是发送方维护的一个 的状态变量,它会根据网络的拥塞程度动态变化的

拥塞窗口 cwnd 变化的规则:

  • 只要网络中没有出现拥塞,cwnd 就会增大;
  • 但网络中出现了拥塞,cwnd 就减少;

发送窗口swnd和接收窗口rwnd是约等于的关系,在引入拥塞窗口的概念后,此时发送窗口的值是swnd=min(cwnd, rwnd),也就是拥塞窗口和接收窗口的最小值。

怎么知道当前网络是否出现了拥塞呢?

其实只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了用拥塞

拥塞控制有哪些控制算法?

  • 慢启动
  • 拥塞避免
  • 拥塞发生
  • 快速恢复

慢启动

连接建立完成后,一开始初始化cwnd=1,以后每次接收到一个ACK,拥塞窗口cwnd的大小就会*2。此时拥塞窗口处于指数增长

慢启动有个启动门限ssthresh状态变量。

  • cwnd < ssthresh时,使用慢启动算法
  • cwnd >= ssthresh时,就会使用 拥塞避免算法

拥塞避免算法

当拥塞窗口cwnd超过慢启动门限ssthresh时,就会进入拥塞避免算法:每当收到一个ACK时,cwnd增加1/cwnd。此时拥塞窗口处于线性增长

一直这么增长着,网络就会慢慢进入拥塞的状况,于是就会出现丢包现象,这时就需要对丢失的数据包进行重传。此时触发了重传机制,也就进入了[拥塞发生算法]

拥塞发生

网络出现拥塞,也就是会发生数据包重传,重传机制主要由两种:

  • 超时重传
  • 快速重传

发生超时重传时的拥塞发生算法

  • 门限值ssthresh设为cwnd/2
  • cwnd重置为1

发生快速重传的拥塞发生算法

  • cwnd=cwnd/2,也就是设置为原来的一半
  • ssthresh = cwnd;
  • 进入快速恢复算法

快速恢复

快速重传和快速恢复算法一般同时使用,快速恢复算法认为你还能收到3个重复ACK,证明网络没有那么糟。

进入快速恢复之前,cwnd和ssthresh已被更新了。

进入快速恢复算法如下:

    • cwnd = ssthresh + 3
    • 重传丢失的数据包
    • 如果再收到重复的ACK,那么cwnd增加1
    • 如果收到新数据的ACK,设置cwnd为ssthresh,接着进入拥塞避免算法。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值