乐趣区

关于计算机网络:笔记计算机网络-5-TCP

综述

UDP 报文是不牢靠的,而 TCP 报文提供牢靠交付,有拥塞管制,是有状态的连贯。而这些个性都是一些简单的构造保障的,非常明显的一点就是,UDP 头部简略,而 TCP 头部简单。尽管 TCP 有所谓的可靠性保障,然而其网络环境不见得良好。作为 IP 层,如果网络条件差,那么发包就没有任何保障,作为下层的 TCP 也没有方法,只能一直重传,通过算法保障可靠性。所以,本文由以下几点组成:

  • TCP 头部格局
  • 三次握手,其中蕴含了 TCP 报文序号是怎么生成的
  • 四次挥手
  • 流量管制和拥塞管制应用到的数据结构
  • 流量管制
  • 拥塞管制
  • 补充:程序问题和丢包问题 —— 超时重传、疾速重传

TCP 的重点问题是:程序问题 丢包问题 连贯保护 流量管制 拥塞管制

TCP 头部格局

TCP 头部的组成部分如下图所示:

  • 源端口号 目标端口号。有了这两个端口,才晓得 TCP 中的数据应该发送给哪个利用
  • 序号。给包编号,是为了解决乱序的问题,如此 TCP 能力保障所有的包都是按序达到的
  • 确认序号。对收回去的包的回复,用来确认对方是否曾经收到,如果没有收到那么就要从新发送,直到送达为止。即使接管方收不到数据包,发送方也晓得哪个包没有被收到,须要重传。这个构造就解决了丢包的问题

    为了保障程序性,所以每一个包都有一个 ID。在建设连贯的时候,会约定起始的 ID 是什么,而后依照 ID 一个个发送。为了保障不丢包,对于发送的包都要进行应答,然而应答不是收一个应答一个,而是会应答某个之前的 ID,示意都收到了,这种模式称为累计确认或者累计应答。例如发送的确认号是 20,示意后面 19 个包都曾经收到了,须要第 20 个包

  • 首部长度字段。因为前面 TCP 选项字段的起因,TCP 首部的长度是可变的
  • 状态位。SYN 是发动一个连贯;ACK 是一个回复;RST 是从新连贯;FIN 是完结连贯;PSH 被置位时,批示接管方应立即将数据交给下层;URG 用来批示报文段里存在着被发送端的下层实体设置为 “ 紧急 ” 的数据,紧急数据的最初一个字节有前面紧急指针字段指出。因为 TCP 是面向连贯的,所以这些状态位就会扭转连贯的状态。

在实践中,PSH、URG 和紧急数据指针并没有应用,只是为了完整性,所以才提到这些字段

  • 窗口大小。TCP 有流量管制的性能,通信的单方都申明一个窗口大小,表明各自的解决能力。除了流量管制,TCP 还会进行拥塞管制,管制本人发包的速度,来适应网络环境

    连贯治理

    接下来是 TCP 的连贯治理,分为三次握手和四次挥手。而拥塞管制和流量管制的局部,在最初形容

    三次握手

    两台主机之间建设 TCP 连贯,须要进行 “ 申请 -> 应答 -> 应答之应答 ” 的三个步骤。三次握手的过程中,除了建设连贯以外,TCP 头部中的序号也会在握手过程中确认下来。

有一个很显著的问题是,为什么 TCP 的握手次数是 3 次,而不是两次或者是 4 次?
答:假如主机 A 和服务器 B 之间的通路是不牢靠的,所以当 A 要发动一个连贯时,会给 B 发送一个包,然而两头的通路是不牢靠的,所以可能这个包丢了,也可能超时了,也可能 B 的确收到了,然而不想和 A 连贯。所以 A 和 B 之间只进行一次交换是不够的

而如果因为通路起因,须要一直由接管方确认曾经收到发送方收回的包,那么就算是四次,也是不够的,因为通路起因,收回的包总会产生失落的状况。如此便停留在了建设连贯时,前面的数据也就不能发送了。

握手三次,对于 A 和 B 都是发出请求,而且收到了回复,大概率曾经没问题了,连贯曾经建设好了。而且,建设连贯就是为了发送数据的,即使是有一个确认包失落,有数据传送,问题天然就解决了

也就是,三次握手,保障了连贯可能建设,而且额定耗费的资源起码

  1. 客户端先向服务器端发送一个 TCP 报文。该报文中不蕴含应用层数据,然而报文首部的一个标记位 (SYN) 被置为 1。此外客户端还会随机抉择一个初始序号 “client\_isn”,这个序号会随着第一次握手,发往服务器
  2. 服务器收到包后,会为这个 TCP 连贯调配缓存和变量,并向客户端发送容许连贯的报文。服务器发送的确认信息的报文里,也不蕴含应用层的数据,然而其首部蕴含有其余信息:SYN 状态位值为 1;首部的确认号字段设置为 “client\_isn + 1″;服务器设置了本人的初始序号 “server\_isn”,并将其搁置到报文首部的序号字段中
  3. 收到服务器发来的确认信息后,客户端也要给这个连贯调配缓存和变量。而后客户端向服务器发送 “ 应答之应答 ” 的报文,在这个报文中,TCP 头部的确认号的值是: “server\_isn + 1″。而且此时连贯曾经建设,所以 SYN 的值是 0. 而且,能够在这个报文中的数据局部,增加客户端要发送给服务器的数据

以下是应用图示,示意在三次握手的过程中,客户端和服务器状态的变动:

  1. 最开始二者都处于敞开状态。而后服务器开启,被动监听某个端口,变成 LISTEN 状态
  2. 客户端发动连贯,之后便处于 SYN\_SENT 状态
  3. 服务端收到客户端发来的连贯,返回 SYN 并且确认 (ACK) 客户端的 SYN。之后就处于 SYN\_RCVD 状态
  4. 客户端收到服务器发来的 SYN 和 ACK 之后,再发送 ACK 的 ACK,之后就处于 ESTABLISHED 状态,因为站在客户端的角度,收回去的连贯,有了回复,就认为连贯曾经建设好了
  5. 服务器收到 ACK 的 ACK,也处于 ESTABLISHED 状态,因为站在服务器的角度看,它也达到了发送的连贯有了回复的状态。二者都处于 ESTABLISHED 状态后,就能够相互发送数据了

序号生成的规定

上述形容中,各个报文的序号应用了单词来进行形容,理论状况中则是数字。而应用的数字,也有肯定的规定:

首先,序号不能从 1 开始,因为会发生冲突。假如 A 连上 B 之后,发送了 1、2、3 三个包,然而发送 3 的时候,因为各种起因 3 没有达到。起初 A 掉线了,从新与 B 建设连贯后,序号又从 1 开始,而后发送 2,并且没有 3,然而上次绕路的那个 3 又回来了,发给了 B,B 天然认为,这就是下一个包,于是产生了谬误
每个连贯都要有不同的序号,序号的起始值是变动的,能够看作是一个 32 位的计数器,每 4 微秒加 1,如果要产生反复的话,那么得须要 “2^32 / 1000 / 1000 / 3600” 个小时 (大概是 4 个多小时),绕路的包早已被抛弃 (下一层里的 IP 头部有 TTL 表明了生存工夫)

四次挥手

TCP 连贯治理的局部,除了三次握手以建设连贯外,还有四次挥手从而断开连接

现实状况下断开连接的过程

客户端和服务器彼此断开连接的过程如下图所示:

  1. 断开连接之前,单方都处于 ESTABLISHED 相互发送数据的状态,而后客户端发送一个 FIN 标记位为 1 的报文给服务器,进入 FIN\_WAIT\_1 的状态,而后期待服务器发送一个确认报文
  2. 处于 FIN\_WAIT\_1 状态的客户端收到来自服务器的确认时,进入 FIN\_WAIT\_2 状态,期待来自服务器断开连接的报文 (这个报文中,FIN 状态位为 1,示意服务器也筹备断开连接了)
  3. 处于 FIN\_WAIT\_2 状态的客户端,收到来自服务器的报文后,会发送一个确认报文,并进入 TIME\_WAIT 状态。理论状况中,收回的 ACK 报文可能会失落,所以客户端会处在 TIME\_WAIT 状态一段时间,理论使用中个别是 30 秒或 1 分钟、2 分钟。期待过后,连贯正式敞开,客户端开释所有资源 (包含端口号)

理论状况中的断开连接

上述断开连接的过程,属于网络条件良好的状况,每个数据包都能达到目的地,不会产生失落的状况。但理论中,会产生许多意外状况。

当 A 筹备断开连接的时候,发送 FIN 为 1 的包之后,就进入 FIN\_WAIT\_1 的状态,B 收到 A 发送的报文之后,就发送一个确认信息,进入 CLOSE\_WAIT 的状态

A 收到 B 发来的确认报文后,就进入 FIN\_WAIT\_2 的状态,如果此时 B 间接开释资源,那么 A 将永远在这个状态。TCP 协定外面并没有对这个状态的解决,然而 Linux 有,能够调整 tcp\_fin\_timeout 这个参数,设置一个超时工夫。

如果 B 没有开释资源,而是向 A 发送了 FIN 为 1 的包时,A 发送 ACK 后,就从 FIN\_WAIT\_2 状态完结。实践上 A 能够开释资源了,然而如果最初的 ACK 失落,B 就会从新发一个 FIN 为 1 的包,此时若 A 曾经开释资源的话,B 就再也收不到 ACK 了,因此 TCP 协定要求 A 最初期待一段时间 TIME\_WAIT,这个工夫要足够长,长到如果 B 没收到 ACK 的话,B 筹备断开连接的包会重发,A 会从新发一个 ACK 并且足够工夫达到 B

A 要等到足够长的工夫的起因是,端口占用问题,以及继续期待问题:

A 间接开释资源时,会一并将原先占用的端口开释,然而 B 不晓得对应的端口上曾经不是 A 了,而 B 原来发过的很多包很可能还在路上,如果 A 的端口被一个新的利用占用了,这个新的利用会收到上个连贯中 B 发过来的包,尽管序列号是从新生成的,然而还是得上一个双保险,避免产生凌乱,因此也须要等足够长的工夫,等到原来 B 发送的所有的包都被抛弃,再空出端口来

此处的等待时间设置为 2 MSL (Maximum Segment Lifetime,报文最大生存工夫),1 MSL 是任何报文在网络上存在的最长工夫,超过这个工夫报文将被抛弃。因为 TCP 报文基于是 IP 协定的,而 IP 头中有一个 TTL 值,是 IP 数据报能够通过的最大路由数,每通过一个解决该报文的路由器此值就减 1,当此值为 0 则数据报将被抛弃,同时发送 ICMP 报文告诉源主机。协定规定 MSL 为 2 分钟,理论利用中罕用的是 30 秒,1 分钟和 2 分钟等

另一个异样问题就是,B 超过了 2MSL 的工夫,仍然没有收到它发的 FIN 的 ACK,B 就会重发 FIN,这个时候 A 再收到这个包之后,A 曾经等了 2MSL 的工夫了,曾经惨绝人寰了,之后的包就都不认了,于是就间接发送 RST 而不再发送 ACK,B 就晓得 A 曾经开释资源了

管制原理

TCP 建设连贯和断开连接的过程形容结束后,就是连贯过程中的一些管制。客户端和服务器之间发送数据时,TCP 有 流量管制 拥塞管制 两种机制

流量管制是为了 打消发送方使接管方缓存溢出 的可能性,也就是说,流量管制是一个速度匹配的服务,发送方的发送速率要和接管方应用程序的读取速率相匹配

拥塞管制指的是,发送方因为 IP 网络的拥挤而被克制,这种模式的管制才叫拥塞管制。尽管二者的动作类似,然而它们是针对不同的起因而采取的措施

因为流量管制和拥塞管制的动作类似,所以在进行管制时,它们 都会应用到窗口,上面就是窗口的构造和相干的概念,窗口中的数字,是发包时的序号,此处为了简便假设序号从 1 开始

发送端的缓存里,有一系列的包,依据解决状况能够分为以下四种:

  • 曾经发送结束,而且曾经收到确认的包
  • 曾经发送然而还没有收到确认信息的包
  • 还没有发送,然而曾经期待发送的包
  • 没有发送,而且临时也不筹备发送的包

于是,接管方会通知发送方一个窗口的大小,叫做 Advertised window. 这个窗口的大小等于下面第二局部与第三局部的和,也就是曾经发送并期待确认的,以及筹备发送的。超过这个大小接管方的缓存可能会溢出,于是发送方须要保护上面的数据结构:

  • LastByteAcked:第一局部和第二局部的分界线
  • LastByteSent:第二局部和第三局部的分界线
  • LastByteAcked + AdvertisedWindow:第三局部和第四局部的分界线

接管方的缓存中,记录的内容如下

  • 承受并且确认过的
  • 还没接管,然而马上就能接管的。也就是接管方可能承受的最多报文数量
  • 还没接管,也没法接管的。也就是会使得缓存溢出的局部

对应的数据结构如下所示:

  • MaxRcvBuffer:最大缓存的量
  • LastByteRead: 是图中最左侧的箭头。之前的是曾经接管了而且曾经被应用层读取了;之后是曾经接管了,然而还没被应用层读取的
  • NextByteExpected: 这个箭头左侧是曾经确认接管的,右侧是期待接管的

NextByteExpected 和 LastByteRead 的差是还没被应用层读取的局部占用掉的 MaxRcvBuffer 的量,用 A 示意。后面提到的,接管方要传递给发送方的窗口的大小 AdvertisedWindow 是 MaxRcvBuffer 减去 A。也就是:AdvertisedWindow = MaxRcvBuffer – (NextByteExpected – LastByteRead)。

NextByteExpected 加 AdvertisedWindow 就是第二局部和第三局部的分界线,其实也就是 LastByteRead 加上 MaxRcvBuffer。其中第二局部外面,因为受到的包可能不是程序的,会呈现空档,只有和第一局部间断的,能够马上进行回复,两头空着的局部须要期待,哪怕前面的曾经来了。这是因为要保障包的程序性

介绍完具体的数据结构,上面就是具体在流量管制和拥塞管制里的利用

流量管制

TCP 通过让发送方保护一个叫做 接管窗口 (receive window,也就是下面提到的 Advertised window) 的变量来提供流量管制的服务。这个变量用来告诉发送方,接管方还有多少可用的缓存空间。而 TCP 是全双工通信,所以客户端和服务器 都有接管窗口

接下来通过一个案例,来阐明流量管制中的原理。还是应用上述数据结构中的图:

图中红色框示意的就是窗口,先假如这个窗口是不变的,始终是 9. 当收到 4 号包的 ACK 后,这个窗口会右移一格,所以第 13 号包也就能够发送了。而假如发送方一下子将 10 ~ 13 号包全副发送后,那么就会进行发送,未发送可发送的局部就变成了 0:

当接管到 5 号包的 ACK 后,窗口又会向右挪动一格,所以第 14 号包也能够发送了:

如此窗口始终向右挪动,就是失常发包的状况。如果接管方解决的很慢,导致缓存中没有空间能够接管发送方发过来的包了,就能够通过 ACK 信息批改发送方窗口的大小,甚至能够设置为 0 以便让发送方暂停发送。以下就是窗口能够更改的状况:

假如接管方的利用始终不读取缓存中的数据,所以当发送方收到 6 号包的 ACK 后,窗口须要放大变成 8。所以这个长度为 8 的窗口,在 6 号包的 ACK 达到的时候,并没有整体向右挪动一格,而是仅左侧挪动,使得窗口放大:

如果此时接管方还是始终不解决数据,那么窗口会始终放大始终放大直到放大为 0 为止。如下图所示,当发送方收到 14 号包的 ACK 时,整个窗口会被调整为 0 从而进行发送

如果这样的话,发送方会定时发送窗口探测数据包,看是否有机会调整窗口的大小。当接管方比较慢的时候,要避免 低能窗口综合征,别空出一个字节来就赶快通知发送方,而后马上又填满了,能够当窗口太小的时候,不更新窗口,直到达到肯定大小,或者缓冲区一半为空,才更新窗口。

以上就是 TCP 流量管制的机制

下面提到的低能窗口综合征,是这样的 (A 是发送方,B 是接管方)。这个景象产生的条件是 B 的接管缓存曾经满了,而且 B 没有数据要发送给 A 了。在这两个条件下,当 B 的利用将缓存中的数据读入,而后清空缓存后,TCP 并不会向 A 发送 rwnd 曾经不为 0 的报文,因为此时 B 没有数据要发送给 A。如此,A 会始终认为 B 的接管缓存是满的,也就是 A 被阻塞而不能再发送新数据了。

解决这个问题的办法是,TCP 规定了,当 B 的接管窗口变为 0 是,主机 A 持续发送只有一个字节数据的报文段,这些报文段将会被接管方确认,最终缓存将开始清空,并且 ACK 里将蕴含一个非 0 的 rwnd 值

拥塞管制

拥塞管制和流量管制一样,也应用了窗口机制。流量管制应用的滑动窗口 rwnd 是怕发送方把接管方缓存塞满,而拥塞管制的拥塞窗口 cwnd,是怕把网络塞满。有一个公式:LastByteSent – LastByteAcked <= min {cwnd, rwnd}, 这个公式示意拥塞窗口和滑动窗口独特管制发送的速度。网络上通道的容量 = 带宽 * 往返提早。

上面是一个 TCP 发包的例子,失常状况下,设置发送窗口 (就是曾经发送然而还没有收到确认的局部) 为通道的容量,就能塞满整个通道。然而若此时增大窗口,使得单位工夫内发送更多的包,容易造成丢包;而如果此时减少通路上路由器的缓存,那么会减少时延,容易产生超时重传的景象。

如图所示,假如往返工夫为 8s,来回各 4 秒,每秒发送一个包,每个包 1024byte。曾经过来了 8s,则 8 个包都收回去了,其中前 4 个包曾经达到接收端,然而 ACK 还没有返回,不能算发送胜利。5-8 后四个包还在路上,还没被接管。这个时候,整个管道正好撑满,在发送端,已发送未确认的为 8 个包,正好等于带宽,也即每秒发送 1 个包,乘以来回工夫 8s。

此时增大发送方的窗口,在单位工夫内发送更多的包。原来发送一个包,从一端达到另一端,假如一共通过四个设施,每个设施解决一个包工夫消耗 1s,所以达到另一端须要消耗 4s,如果发得更快,则单位工夫内,会有更多的包达到这些中间设备,这些设施还是只能每秒解决一个包的话,多进去的包就会被 抛弃

此时若减少中间设备的缓存,使得解决不过去的包先放在队列外面,这样包就不会失落,然而毛病是会 减少时延,导致这些缓存的包花 4s 也达到不了接收端,而且如果时延达到肯定水平,就会超时重传,

于是 TCP 的拥塞管制次要来防止两种景象,包失落 超时重传。一旦呈现了这些景象就阐明,发送速度太快了,要慢一点。而最开始的时候,发送小包,而后包的大小再一点点增大,这个过程叫做慢启动

TCP 刚建设连贯的时候,会把 cwnd 设置为一个报文段,一次只能发送一个;当收到这一个确认的时候,cwnd 加一,于是一次可能发送两个;当这两个的确认到来的时候,每个确认 cwnd 加一,两个确认 cwnd 加二,于是一次可能发送四个;当这四个的确认到来的时候,每个确认 cwnd 加一,四个确认 cwnd 加四,于是一次可能发送八个。能够看出这是指数性的增长。

然而这种指数增长也有止境,有一个值 ssthresh 为 65535 个字节,当超过这个值的时候,就不能再指数增长了,因为可能整个通路都快满了。所以,在超过 ssthresh 之后,每收到一个确认,cwnd 减少 1/cwnd,从上述 rwnd 的值为 8,一次发送八个,当八个确认到来的时候,每个确认减少 1/8,八个确认一共 cwnd 减少 1,于是一次可能发送九个,变成了线性增长。

然而线性增长也还在增长,增长到开始呈现拥塞,此时就必须升高发包的速度了。

拥塞的一种表现形式是丢包,须要超时重传。传统的形式是这样的,将 sshresh 设为 cwnd/2,将 cwnd 设为 1,从新开始慢启动。然而这种形式太激进了,将一个高速的传输速度一下子停了下来,会造成网络卡顿。

新型的形式是,采纳上面很快会提到的 “疾速重传算法“。当接收端发现丢了一个两头包的时候,发送三次前一个包的 ACK,于是发送端就会疾速地重传,不用期待超时再重传。TCP 认为这种状况不重大,因为大部分没丢,只丢了一小部分,所以 cwnd 减半为 cwnd/2,而后 sshthresh = cwnd,当三个包返回的时候,cwnd = sshthresh + 3,也就是略微升高了一些速度,留有线性增长的空间。上面这张图片,就是采纳这两种办法时,发送速度的变动:

拥塞管制 – TCP BBR 拥塞算法

TCP 的拥塞管制,使得在时延很重要的状况下,反而升高了速度。然而拥塞管制次要来防止的两个景象都是有问题的:

  1. 丢包的问题。产生丢包并不一定就示意,网络通道曾经被填满了,即使是带宽不满的时候,也可能产生丢包
  2. TCP 的拥塞管制要等到将中间设备都填充斥了,才产生丢包,从而升高速度,这时候曾经晚了。其实 TCP 只有填满网络通路就能够了,不应该持续填充直到连缓存也被填满。

为了解决下面两个问题,就有了 TCP BBR 算法。这个算法试图找到一个平衡点,就是通过一直地放慢发送速度,将管道填满,然而不填满中间设备的缓存,从而防止减少时延。在这个平衡点上,就能够很好的达到高带宽和低时延的均衡。

程序问题和丢包问题

接下来形容的是,TCP 要保障程序性时遇到的问题。简略来说就是,因为产生了丢包,导致接管时程序产生了变动,所以须要从新发送没有达到的包。而确定发送的机会,有两种办法,一种是 超时重传 ,另一种是 疾速重传

在这一部分,还是应用上文中介绍数据结构时的图片,下面一张是发送方的图片,上面一张是接管方的图片

此刻在发送方,1、2、3 曾经收回并且曾经收到了确认;4 ~ 9 是曾经发送进来然而没有失去确认的的包;10、11、12 是筹备发送但还没有发送的包;前面几个包是接管方没有足够的空间,目前还不能发送的包。在接收端来看,1、2、3、4、5 是曾经实现 ACK,然而没读取的;6、7 是期待接管的;8、9 是曾经接管,然而没有 ACK 的。

发送端和接收端以后的状态:1、2、3 没有问题,单方达成了统一;4、5 接管方说 ACK 了,然而发送方还没收到,有可能丢了,有可能在路上;6、7、8、9 曾经发送,然而 8、9 曾经到了,6、7 没到,呈现了乱序,缓存着然而无奈发送 ACK。


假如 4 的 ACK 到了,而 5 的 ACK 丢了,6、7 的数据包丢了,采取的方法如下:

一种办法就是 超时重试,也即对每一个发送了,然而没有 ACK 的包,都设一个定时器,超过了肯定的工夫,就从新尝试。然而这个工夫不宜过短,工夫必须大于往返工夫 (英文名叫 RTT),否则会引起不必要的重传;也不宜过长,这样超时工夫变长,拜访就变慢了

预计往返工夫,须要 TCP 通过采样 RTT 的工夫,而后进行加权均匀,算出一个值,而且这个值会因为网络情况的变动而一直变动。除了采样 RTT,还要采样 RTT 的稳定范畴,计算出一个预计的超时工夫。因为重传工夫是一直变动的,咱们称为 自适应重传算法(Adaptive Retransmission Algorithm)。

如果过一段时间,5、6、7 都超时了,就会从新发送。接管方发现 5 原来接管过,于是抛弃 5;6 收到了,接管方发送 ACK,要求下一个是 7,但 7 可怜又丢了。当 7 再次超时的时候,就是须要重传的时候,TCP 的策略是 超时距离加倍。每当遇到一次超时重传的时候,都会将下一次超时工夫距离设为先前值的两倍。两次超时,就阐明网络环境差,不宜频繁重复发送。

超时触发重传存在的问题是,超时周期可能绝对较长。而且须要统计 RTT 及其稳定范畴,无疑减少了工作量。所以就有 第二种办法 能够抉择:疾速重传

疾速重传的机制是:当接管方收到一个序号大于下一个所冀望的报文段时,就会检测到数据流中的一个距离,于是它就会发送冗余的 ACK,ACK 的值是冀望接管的报文段。而当客户端收到三个冗余的 ACK 后,就会在定时器过期之前,重传失落的报文段

例如,6 号报文和 8 号报文接管方都收到了,就是没有收到 7 号报文,所以很大可能 7 号报文丢了。于是发送 6 的 ACK,要求下一个是 7。而后收到后续的包,依然发送 6 的 ACK,要求下一个是 7。当客户端收到 3 个反复 ACK,就会发现 7 确实丢了,不等超时,马上重发

还有一种形式称为 Selective Acknowledgment(SACK)。这种形式须要在 TCP 头里加一个 SACK 的货色,能够将缓存的地图发送给发送方。例如能够发送 ACK6、SACK8、SACK9,有了地图,发送方一下子就能看进去是 7 丢了

退出移动版