面试热门题! 网络协议(一)

115 阅读26分钟

应用层

简单介绍http和https

http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准,用作从服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效。

https: 是 HTTP 的安全版,即 HTTP 下加入 SSL/TSL层。https 协议的主要作用是:建立一个信息安全通道,来确保数据传输的真实性。

HTTPS的加密方式

在证书校验通过的情况下,HTTPS会先进行非对称加密,然后再通过对称加密传输数据。

非对称加密:客户端生成随机数key,并通过公钥对key进行加密并传给服务端。服务端则用私钥对这个key进行解密。至此双方都确定后续进行数据传输时对称加密所用的密钥--key。

对称加密:客户端和服务端之间在进行数据传输时会将key 当成密钥,通过对称加密的方式进行加密数据

如何确定HTTPS的公钥在传输过程中没被篡改

首先我们得了解数字证书包括证书序列号、证书有效期和公开密钥等信息。

数字证书中的数字签名是CA机构(利用自身私钥)经过哈希加密处理生成的。

客户端拆解数字证书后得到数字签名及其他明文信息。如果 利用公钥对数字签名进行解密得到的值和经过哈希解密数字签名得到的值相等,那么表示公钥未被篡改。

HTTP方法

HTTP/1.0 定义了三种请求方法:GET, POST 和 HEAD 方法。

HTTP/1.1 增加了六种请求方法:OPTIONS, PUT, PATCH, DELETE, TRACE 和 CONNECT 方法

方法名作用
GET请求指定的页面信息,并返回具体内容,通常只用于读取数据。
POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立或已有资源的更改。
HEAD类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。
PUT替换指定的资源,没有的话就新增。
DELETE请求服务器删除 URL 标识的资源数据。
CONNECT将服务器作为代理,让服务器代替用户进行访问。
OPTIONS向服务器发送该方法,会返回对指定资源所支持的 HTTP 请求方法。
TRACE回显服务器收到的请求数据,即服务器返回自己收到的数据,主要用于测试和诊断。
PATCH是对 PUT 方法的补充,用来对已知资源进行局部更新。

GET 和 POST 的区别

  • get 提交的数据会放在 URL 之后,并且请求参数会被完整的保留在浏览器的记录里,由于参数直接暴露在 URL 中,可能会存在安全问题,因此往往用于获取资源信息。而 post 参数放在请求主体中,并且参数不会被保留,相比 get 方法,post 方法更安全,主要用于修改服务器上的资源。
  • get 请求只支持 URL 编码,post 请求支持多种编码格式。
  • get 只支持 ASCII 字符格式的参数,而 post 方法没有限制。
  • get 提交的数据大小有限制(GET 方法是通过 URL 传递数据的,而 URL 本身并没有对数据的长度进行限制,真正限制 GET 长度的是浏览器。IE 浏览器对 URL 的最大限制为 2000多个字节,大概 2KB, Chrome:8182 字符, FireFox: 65536字符),而 post 方法提交的数据没限制
  • get 方式需要使用 Request.QueryString 来取得变量的值,而 post 方式通过 Request.Form 来获取。
  • get 方法产生一个 TCP 数据包,post 方法产生两个(post先发送header 再发送 data)(并不是所有的浏览器中都产生两个,Firefox就只发送一次)。

HTTP如何保存用户状态

1.基于 Session 实现的会话保持

在客户端第一次向服务器发送 HTTP 请求后,服务器会创建一个 Session 对象并将客户端的身份信息以键值对的形式存储下来,然后分配一个会话标识(SessionId)给客户端,这个会话标识一般保存在客户端 Cookie 中,之后每次该浏览器发送 HTTP 请求都会带上 Cookie 中的 SessionId 到服务器,服务器根据会话标识就可以将之前的状态信息与会话联系起来,从而实现会话保持。

优点:安全性高,因为状态信息保存在服务器端。

缺点:由于大型网站往往采用的是分布式服务器,浏览器发送的 HTTP 请求一般要先通过负载均衡器才能到达具体的后台服务器,倘若同一个浏览器两次 HTTP 请求分别落在不同的服务器上时,基于 Session 的方法就不能实现会话保持了。

【解决方法:采用中间件,例如 Redis,我们通过将 Session 的信息存储在 Redis 中,使得每个服务器都可以访问到之前的状态信息】

2.基于 Cookie 实现的会话保持

当服务器发送响应消息时,在 HTTP 响应头中设置 Set-Cookie 字段,用来存储客户端的状态信息。客户端解析出 HTTP 响应头中的字段信息,并根据其生命周期创建不同的 Cookie,这样一来每次浏览器发送 HTTP 请求的时候都会带上 Cookie 字段,从而实现状态保持。基于 Cookie 的会话保持与基于 Session 实现的会话保持最主要的区别是前者完全将会话状态信息存储在浏览器 Cookie 中。

优点:服务器不用保存状态信息, 减轻服务器存储压力,同时便于服务端做水平拓展。

缺点:该方式不够安全,因为状态信息存储在客户端,这意味着不能在会话中保存机密数据。除此之外,浏览器每次发起 HTTP 请求时都需要发送额外的 Cookie 到服务器端,会占用更多带宽。

HTTP头部包含的信息

通用头:是客户端和服务器都可以使用的头部,可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能,如Date头部。

请求头:是请求报文特有的,它们为服务器提供了一些额外信息,比如客户端希望接收什么类型的数据,如Accept头部。

响应头:便于客户端提供信息,比如,客服端在与哪种类型的服务器进行交互,如Server头部。

实体头:指的是用于应对实体主体部分的头部,比如,可以用实体头部来说明实体主体部分的数据类型,如Content-Type头部。

如何知道HTTP的报文长度

对于小点的文件,例如图片或者静态页面等,服务器明确知道请求内容大小的,会直接给出content-length,也就是本次返回的数据长度

对于大文件,服务端利用分块传输编码的方式,使用 Transfer-Encoding:chunked 字段进行返回报文。 虽然无法明确报文的长度,但是客户端知道是分块传输,收到了数据后会先进行组装。

HTTP1.0 和1.1的区别

长连接 HTTP1.0默认浏览器和服务器之间是短连接,服务器发送完之后会直接关闭TCP连接,如果想多个HTTP请求复用TCP连接,需要在头部里增加Connection:Keep-Alive ; HTTP1.1的时候默认使用持久连接,减少了资源消耗

缓存处理: 在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

节约带宽: 当客户端请求某个资源时,HTTP1.0默认将该资源相关的整个对象传送给客户端且不支持断点续传。HTTP1.1请求头新增了range字段,支持客户端只请求部分资源,因此开发者可以多线程请求某一资源,从而充分的利用带宽资源,实现高效并发。

错误通知的管理:1.1增加了一些错误状态响应码(24个),比如410表示请求的资源已经被永久删除

Host首部: HTTP1.0时期认为一台服务器只会绑定唯一的ip地址,且ip地址和服务器是一对一的,因此请求的信息中不会携带主机名;但是后来虚拟主机的出现,一台服务器可以存在多个主机,但是他们的IP地址却是相同,为了区分不同的主机信息,因此HTTP1.1增加了Host首部(由主机名和端口构成),若请求消息没HOST信息,则返回400

HTTP/1.X 和 2.0的区别

头部压缩: HTTP/2.0 通过 gzip 和 compress 压缩头部然后再发送,同时通信双方会维护一张头信息表,所有字段都记录在这张表中,在每次 HTTP 传输时只需要传头字段在表中的索引即可,大大减小了重传次数和数据量。

二进制格式: HTTP2.0中请求头和请求体都是采用的二进制进行传输(把数据分成帧,帧组成了数据流,流具有流 ID 标识和优先级),相比于1.0请求头文本传输,请求体文本/二进制传输,效率上更快

多路复用: HTTP2.0实现了同一TCP连接下多个请求同时进行,因为每个请求的数据流都有各自的流id,可以定位到是哪个服务端的请求

服务端推送: HTTP2.0 支持服务端给客户端主动推送信息。

http和https的区别

https比http多了SSL协商过程,因此会比http稍慢;

http是明文传输,安全性低;https是加密传输,安全性高;

HTTPS需要数字认证机构认证的安全证书,是需要花钱的,http则无。

介绍webSocket

HTML5开始提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。

cookie session 区别

  1. cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
  2. cookie 不是很安全,别人可以分析存放在本地的 cookie 并进行 cookie 欺骗。考虑到安全应当使用session。
  3. session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用cookie。
  4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

cookie、sessionStorage、localStorage 的区别

数据存储大小

cookie 数据不能超过 4K

sessionStorage localStorage 可以达到 5M 或更大

数据的有效期不同

sessionStorage:仅在当前的浏览器窗口关闭前有效;

localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;

cookie:只在设置的cookie过期时间之前一直有效,即使窗口和浏览器关闭

作用域不同

sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;

localStorage:在所有同源窗口都是共享的;

cookie:也是在所有同源窗口中共享的,始终在同源的 http 请求中携带(即使不需要)

常见状态码

状态码分类

分类分类描述
1XX指示信息--表示请求正在处理
2XX成功--表示请求已被成功处理完毕
3XX重定向--要完成的请求需要进行附加操作
4XX客户端错误--请求有语法错误或者请求无法实现,服务器无法处理请求
5XX服务器端错误--服务器处理请求出现错误

100: 客户端继续处理请求

101: 切换协议。服务器根据客户端的请求切换到更高级的协议。

200: 响应成功。

204: 无内容。服务器成功处理了请求,但不需要返回任何实体内容

304:返回结果和上次一致

如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个 304 状态码。

400:请求无效

产生原因: 前端提交数据的字段名称和字段类型与后台的实体没有保持一致 前端提交到后台的数据应该是 json 字符串类型,但是前端没有将对象 JSON.stringify 转化成字符串。

解决方法: 对照字段的名称,保持一致性 将 obj 对象通过 JSON.stringify 实现序列化

401:当前请求需要用户验证

403:服务器已经得到请求,但是拒绝执行

404: 查不到资源

500: 服务器异常

fetch

定义:

fetch是用来异步获取资源的接口,它提供了许多与 XMLHttpRequest 相同的功能,但被设计成更具可扩展性和高效性。fetch()返回的 Promise不会被标记为 reject, 除非遇到网络故障或者请求被阻止。

基础用法:

fetch(url,{...config}) // config 包括请求头、请求体、其他首部信息
  .then(response => response.json())
  .then(data => console.log(data)); // 请求成功
  .catch(error => console.log(error));// 请求失败

与Ajax的区别

  • 当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。

  • fetch 不会发送跨域 cookies,除非你使用了 credentials 的初始化选项(credentials: 'include')

与axios的区别

axios基于promise,是对原生XHR的封装,易用性更强;而fetch作为原生api理论上来讲可拓展性和性能上都会更佳。

fetch 发送 2 次请求的原因:

用fetch的post请求的时候,fetch第一次发送了一个Options请求,询问服务器是否支持修改的请求头;如果服务器支持,则在第二次中发送真正的请求。

Keep-Alive 和非 Keep-Alive

非Keep-alive:早期HTTP1.0默认非持久连接,浏览器发起http请求需要与服务器建立新的TCP连接,请求处理后连接立即断开,重新请求重新连接。但每一个这样的连接,客户机和服务器都要分配 TCP 的缓冲区和变量(一定的空间),这给服务器带来的严重的负担。

使用场景:用户数目较多的Web网站的 HTTP 服务。例如电商网站:京东、淘宝


Keep-alive:HTTP1.1默认持久连接,同一客户机可以连续请求通过相同的连接进行传送,一台服务器多个web页面也可通过单个TCP连接传送给同一个客户机。但长时间保持TCP连接会导致系统资源被无效占用。为此可以通过合理的设置KeepAliveTimeout参数值,来实现一定时间后断开连接。

使用场景:多用于操作频繁,点对点的通讯,而且客户端连接数目较少的情况。例如即时通讯、网络游戏等。

DNS 的作用和原理

作用: 通常我们有两种方式识别主机:通过主机名或者IP地址。但是我们更喜欢通过记忆主机名来访问地址,域名系统DNS的作用就是将域名映射成为IP地址,让人们更方便地访问互联网。

原理: DNS本质上就是一个分布式数据库,存放域名到ip的映射;同时它又是有层次的,自上而下主要分成根域名DNS、顶级域名DNS、权威域名DNS:

域名解析的过程就可以理解从DNS中找到域名对应的ip映射。 因为DNS的分布式设计,每个DNS服务器中只包含部分的映射关系。所以在查询指定域名时,查询的情况包括递归查询和迭代查询。

迭代查询比较好理解,就是本地DNS服务器按根域名、顶级域名、权威域名自上往下的顺序查找指定域名。当前层级的域名服务器会根据当前查询的域名返回下一层级的域名服务器ip,直到找到指定域名的ip映射

递归查询 其实从客户端发起域名请求到本地DNS服务器返回IP的过程就是递归查询。用回溯的思想看待理想的完整查询ip过程

DNS 为什么用 UDP

更正确的答案是 DNS 既使用 TCP 又使用 UDP。

当进行区域传送(主域名服务器向辅助域名服务器传送变化的那部分数据)时会使用 TCP,因为数据同步传送的数据量比一个请求和应答的数据量要多,而 TCP 允许的报文长度更长,因此为了保证数据的正确性,会使用基于可靠连接的 TCP。

当客户端向 DNS 服务器查询域名 ( 域名解析) 的时候,一般返回的内容不会超过 UDP 报文的最大长度,即 512 字节。用 UDP 传输时,不需要经过 TCP 三次握手的过程,从而大大提高了响应速度,但这要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。

DNS劫持

DNS 劫持即域名劫持,是通过将原域名对应的 IP 地址进行替换从而使得用户访问到错误的网站或者使得用户无法正常访问网站的一种攻击方式。

实现: 1. 获取要劫持的域名信息 2.破解域名注册用的email 3.修改域名注册时IP等的信息 4. 通过email确认修改信息。

防御:

  • 直接通过 IP 地址访问网站,避开 DNS 劫持。
  • 由于域名劫持往往只能在特定的网络范围内进行,因此一些高级用户可以通过网络设置让 DNS 指向正常的域名服务器以实现对目的网址的正常访问,例如将计算机首选 DNS 服务器的地址固定为 8.8.8.8。

套接字

套接字就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。

分类:

  1. 流套接字: 基于 TCP 传输协议,主要用于提供面向连接、可靠的数据传输服务

  2. 数据报套接字: 数据报套接字基于 UDP 传输协议,对应于无连接的UDP服务应用

  3. 原始套接字: 访问其他协议发送的数据必须使用原始套接

用户输入网址到显示对应页面

  1. DNS解析(前面已介绍)

  2. TCP连接 (三次握手,后面介绍)

  3. 发送HTTP请求(客户端给服务端发送请求)

  4. 响应HTTP请求(服务端处理请求后,返回响应的请求)

  5. 浏览器渲染(浏览器根据响应开始显示页面,首先解析HTML文件构建DOM树,然后解析CSS文件生成CSSOM(css规则树) DOM和CSSOM合并后生成Render Tree(渲染树)。等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上)

  6. 断开连接(四次挥手,后面介绍)

传输层

涉及到的内容倾向于TCPUDP,最重要的便是TCP的连接和断开。

TCP报文的组成

序列号: Seq

确认号: Ack

标志符:

  • SYN 同步标志,表示建立连接请求
  • ACK 确认标志,表示确认收到请求
  • FIN 结束标志,用于释放连接,为 1 时表示发送方已经没有数据发送了
  • PSH PUSH标志,当该位为1时,则指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队
  • RST 重置连接标志,出现错误连接时,使用此标志来拒绝非法的请求
  • URG 紧急指针标志,该位为 1 时表示紧急指针有效,为 0 则忽略

这里需要注意的就是:不要将标识符ACK确认符Ack混淆了

首部长度:该字段指示了以 32 比特的字为单位的 TCP 的首部长度。其中固定字段长度为 20 字节,由于首部长度可能含有可选项内容,因此 TCP 报头的长度是不确定的,20 字节是 TCP 首部的最小长度

接收窗口:主要用于 TCP 流量控制。该字段用来告诉发送端其窗口(缓冲区)大小,以此控制发送速率,从而达到流量控制的目的

校验和:奇偶校验,此校验和是对整个 TCP 报文段,包括 TCP 头部和 数据部分。该校验和是一个端到端的校验和,由发送端计算和存储,并由接收端进行验证,主要目的是检验数据是否发生改动,若检测出差错,接收方会丢弃该 TCP 报文。

紧急数据指针:紧急数据用于告知紧急数据所在的位置,在URG标志位为 1 时才有效。当紧急数据存在时,TCP 必须通知接收方的上层实体,接收方会对紧急模式采取相应的处理。

选项:该字段一般为空,可根据首部长度进行推算。主要有以下作用:

① TCP 连接初始化时,通信双方确认最大报文长度。

② 在高速数据传输时,可使用该选项协商窗口扩大因子。

③ 作为时间戳时,提供一个 较为精准的 RTT。

数据:TCP 报文中的数据部分也是可选的,例如在 TCP 三次握手和四次挥手过程中,通信双方交换的报文只包含头部信息,数据部分为空,只有当连接成功建立后,TCP 包才真正携带数据

三次握手

目的确认双方都具备发送和接收的能力

第一次握手: 客户端发送SYN包给服务端,SYN = 1, Seq为随机数x,并且进入SYN-SENT状态,服务端确认客户端的发送正常。

第二次握手 服务端发送SYN/ACK包给客户端,SYN = 1,ACK=1, Ack = x+1, Seq = y,进入SYN-RECV状态,客户端确认服务端的接收和发送正常。

第三次握手

客户端发送ACK包给服务端,ACK =1, Ack = y+1,Seq = x+1,双方都进入ESTABLISHED状态,服务端确认客户端的接收正常。

Ack为啥是接收到的序列号+1: 因为序列号Seq前的数据都已经接收过了,接收端希望下一次发送的序列号是 seq + 1, 确保数据的有序。

四次挥手

第一次挥手:

客户端发送FIN包到服务端,客户端进入FIN-WAIT1,等待服务端确认。

第二次挥手: 服务端确认客户端发来的断开连接请求后,给客户端返回ACK包,并进入CLOSE-WAIT状态。客户端收到包后进入FIN-WAIT2状态

第三次挥手: 服务端做好了断开连接的准备,向客户端发送FIN/ACK包并进入了LAST-ACK状态,等待客户端最后的确认

第四次挥手: 客户端接收服务端的FIN/ACK包后确认了服务端做好了准备,于是给服务端返回了ACK包。此时客户端进入TIME-WAIT状态,服务端在收到包后进入了CLOSED状态,客户端等待完 2 MSL 之后,结束 TIME-WAIT 阶段,进入 CLOSED 阶段,由此完成「四次挥手」

为啥要三次握手而不是两次

  1. 确认双方都具备发送和接收的能力,
  • 第一次握手,服务端确定客户端的发送正常
  • 第二次握手,客户端确认服务端的收发正常
  • 第三次握手,服务端确定客户端接收正常
  1. 在执行两次握手的情况下, 如果网络出现异常,服务端发给客服端的包丢了之后,服务端就直接建立了连接。客户端由于未接收到包,超时后会重新发起请求导致服务端开启新的端口而原来的端口不会释放,造成资源浪费!

为啥要四次挥手而不是三次

客户端发起的断开连接请求只能说明此时客户端不会再发起新的数据请求,但是服务端往客户端传递数据的过程可能还在进行,所以便有了CLOSE-WAIT阶段,因此我们无法将第二第三次的挥手合并成一次。

CLOSE-WAIT 和 TIME-WAIT 的状态和意义

在服务器收到客户端关闭连接的请求并告诉客户端自己已经成功收到了该请求之后,服务器进入了 CLOSE-WAIT 状态,然而此时有可能服务端还有一些数据没有传输完成,因此不能立即关闭连接,而 CLOSE-WAIT 状态就是为了保证服务器在关闭连接之前将待发送的数据发送完成

TIME-WAIT 发生在第四次挥手,当客户端向服务端发送 ACK 确认报文后进入该状态,若取消该状态,即客户端在收到服务端的 FIN 报文后立即关闭连接,此时服务端相应的端口并没有关闭,若客户端在相同的端口立即建立新的连接,则有可能接收到上一次连接中残留的数据包,可能会导致不可预料的异常出现。

除此之外,假设客户端最后一次发送的 ACK 包在传输的时候丢失了,由于 TCP 协议的超时重传机制,服务端将重发 FIN 报文,若客户端并没有维持 TIME-WAIT 状态而直接关闭的话,当收到服务端重新发送的 FIN 包时,客户端就会用 RST 包来响应服务端,这将会使得对方认为是有错误发生,然而其实只是正常的关闭连接过程,并没有出现异常情况

为啥TIME-WAIT需要2MSL的时长,让客户端能在丢包的情况下正常接收到服务端重新发起的FIN包(一次发起请求和一次响应请求)。

MSL指的是一段 TCP 报文在传输过程中的最大生命周期

TCP和UDP的区别

1.连接方面

TCP是面向连接的(如打电话需要拨号建立连接);

UPD是无连接的,发送数据前不需要建立连接

2.安全方面

TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按需到达;适合大数据量的交换

UDP 尽最大努力交付,即不保证可靠交付。

3.传输效率

TCP传输效率相对较低

UDP的传输效率高,适用于对高速传输和实时性有较高要求的通信和广播通信。

4.连接对象的数量

TCP只能是点到点、一对一。

UDP支持一对一、一对多、多对一和多对多的交互通信

5.首部大小

TCP的首部不小于20字节

UDP为8字节

TCP的拥塞控制

目的通过维护这两个核心 拥塞窗口(Congestion Window,cwnd) 慢启动阈值(Slow Start Threshold,ssthresh) ,防止因为网络环境较差发生过载拥塞导致丢包的情况。

方法: 慢启动、拥塞避免、快速重传、快速恢复

慢开始

拥塞窗口在未达到慢启动阈值时,按照指数倍增大。

拥塞避免

拥塞窗口达到慢启动阈值后,窗口增速放慢,每次传输时拥塞窗口大小+1。

快速重传 发生丢包的情况下,接收端返回的确认ACK包始终是最后一次正常接收的而返回的ACK包。再重复三次这个ACK包之后,发送端意识到丢包了,立即对丢包的数据进行重传。慢启动阈值将为上次拥塞窗口大小的一半。

快速恢复 跳过了慢启动阶段,直接进入拥塞避免阶段。慢启动阈值降低为cwnd的一半,cwnd的大小变为拥塞阈值,cwnd线性增加

TCP的流量控制

接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。

发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。

接收端发送的窗口值为0时如何解决: 利用持续计数器和探测报文: 如果发送端收到的接收窗口win = 0,则触发计数器,超时后,发送探测报文。如果探测报文返回的win还是0则再次触发计数器,反之客户端开始发送新数据。