Tcp是什么?_跟你说完了

Tcp是什么?_跟你说完了之前受到Wireshark——从此我就喜欢上了它,就像是学武之人得到了一把称手好剑的启发,带着回顾、深入TCP的目标,回顾了《TCP-IP协议卷1》《图解TCP/IP协议》,受益匪浅。写这篇文章,希望自己能对TCP形成一个系统性的知识沉淀,也希望能给初学者一个基本概念的认识,读完本文再深入书籍,应该也是不错滴。学习路径:1、阅读《TCP-IP协议卷1》的TCP章节(相关知识非常全面,各种算法…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

之前受到Wireshark——从此我就喜欢上了它,就像是学武之人得到了一把称手好剑的启发,带着回顾、深入TCP的目标,回顾了《TCP-IP协议卷1》《图解TCP/IP协议》,受益匪浅。写这篇文章,希望自己能对TCP形成一个系统性的知识沉淀,也希望能给初学者一个基本概念的认识,读完本文再深入书籍,应该也是不错滴。

学习路径:

1、阅读《TCP-IP协议卷1》的TCP章节(相关知识非常全面,各种算法,但是因为拗口的翻译,比较难一时半会理解)

2、过一遍RFC 793 (TCP协议的规定,八几年就订好的,谢谢祖师爷赏口饭吃)

3、阅读《图解TCP/IP协议》的TCP章节(深入浅出,各种图示让你能更好的理解其作用过程,但描述的知识比较少,无法形成知识体系)

4、重复步骤1进行精读并输出xmind

建议最好还是结合 《TCP-IP协议卷1》+《图解TCP/IP协议》一起看,看不懂时可以过一下《图解TCP/IP协议》然后再结合《TCP-IP协议卷1》的实战看

一、总览

本文依据《TCP-IP协议卷1》的知识思路进行总结

1、TCP:传输控制协议(对TCP协议的一个总览,并详解了TCP协议头的构成)

2、TCP连接的建立与终止(主要讲解了TCP的三次握手与四次挥手,并讲述了TCP连接的状态变迁,面试常问)

3、一些TCP的数据交互规则(这一章比较小,主要讲了几个数据交互的规则)

4、TCP成块的数据流(主要讲解了TCP数据传输中会出现的问题和问题解决方案,主要是滑动窗口,面试常问)

5、TCP的超时与重传(主要讲解了当TCP传输时遇到超时的问题如何解决,主要是通过拥塞避免算法)

6、TCP的坚持定时器(讲解一些确认通道可用性的定时器)

7、TCP的未来和性能(一些TCP的周边知识)

二、TCP:传输控制协议

1、TCP是什么?

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

说白了TCP就是一种传输协议,就像HTTP协议一样,HTTP的目的是指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应,而TCP的目的是为了确保数据传输的可靠性,我给你一个数据包,你一定就要收到,收不到的话那么我就会给你重发,直到我超时放弃你了。

HTTP是建立在TCP之上的,当你建立起TCP连接之后,在上面传输的数据用的是HTTP协议。

2、TCP是面向连接的

经过TCP协议定义的三次握手之后,TCP协议建立一条虚拟的连接用于传输数据。

连接是指各种设备,线路,或网络中进行通信的两个应用程序为了相互传递消息而专有的、虚拟的通信线路,也叫虚拟电路。

一旦建立了连接,进行通信的应用程序只使用这个虚拟的通信线路发送和接收数据,就可以保障信息的传输。应用程序可以不用顾虑其链路的问题。TCP则负责控制链接的建立,断开,保持等管理工作。

数据被拆分成数据段,然后改通道进行传输,数据段传输的可靠性由TCP协议来保障。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NuZFVfn-1573580402521)(H:\我的知识库\知识库\计算机网络\TCP-IP详解\TCP是什么看完你就知道了\1572284935419.png)]

3、TCP怎么实现其连接可靠性?

  • 应用数据会被切段(小块数据传输保证通畅)
  • 数据段丢失重传
  • 数据段收到确认
  • 数据段数据校验和
  • 数据段重排序
  • 数据段去重
  • 流量控制

3.1、TCP以段为单位发送数据

在三次握手时,交互通信的双方会把自己最大的消息长度(MSS:Maximum Segment Size)告诉对方,TCP服务会把数据按MSS切分段发送

在这里插入图片描述

3.2、数据段收到确认

在TCP中,当发送端的数据到达接受主机时,接收端主机会返回一个收到消息的通知。这个消息叫做确认应答(ACK)。这个机制就好比我们经常在电视上看到人们经常用对讲机说话,当你收到别人发送的语音时,你都需要回复一句“收到”让发送者明确知道这条消息,可以安心的知道消息已被接受者接受。

在这里插入图片描述

当发送者在一定时间内没有收到接受者的回复时,发送者可以根据重传策略(后面会介绍)进行消息重传,保证消息能真正的发到接受者手中。

在这里插入图片描述

3.3、数据段丢失重传

当数据包丢失的时候,TCP会根据重传策略(后面会介绍)进行消息重传,重传策略包含快速重传,还有超时重传两种场景。

3.4、数据段数据校验和

TCP校验和(Checksum)是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。此时发送端没有收到ACK,便会重新传递一个完好无损的数据包。

3.5、数据段重排序

TCP协议将数据切分为多个小片段(数据被划分为合理长度),小片段由头部(header)和数据(payload)组成,为了确保抵达数据的顺序,TCP协议给每个片段的头部(header)都分配了序列号,接受者可以使用该序列号排序。

3.6、数据段去重

原因与3.5一致,接受者有了一波数据段的序列号,如果ACK因为网络关系没有回复给到发送者,导致发送者重传,那么发送者重传后,接收者可以利用序列号进行去重,并在下一个ACK中回复发送者。

3.7、流量控制

TCP的流量控制主要使用的是滑动窗口协议算法,在后面会有介绍。

以上所述都是TCP连接可靠性的保证,那TCP为什么可以如此强大呢?其中一部分原因呀,是它定义了一个强大的TCP协议头,接下来,我们先来了解这个头,每一个数据段都要携带这么一个头。

4、TCP首部

在这里插入图片描述

字段解析:

  • 端口号:所谓的端口,就好像是门牌号一样,客户端可以通过ip地址找到对应的服务器端,但是服务器端是有很多端口的,每个应用程序对应一个端口号,通过类似门牌号的端口号,客户端才能真正的访问到该服务器。为了对端口进行区分,将每个端口进行了编号,这就是端口号。(软考今年出了一题。。)

  • 序号:对每个数据段做的标记,标志这某个数据段在某个数据中的位置(划重点,发送者利用该序号表示数据段是完整数据的哪一部分,设置的规则是上一个段序号+上一个段长度。接收者利用该序号表示发送者下一个应发送的应该是哪一部分的数据,设置的规则是收到的数据段序号+数据段的长度。接收者回复的ACK序号,是发送者下一个数据段的序号,代表的意思是收到该序号之前的数据段)

  • 标志

    • URG:紧急指针(代表紧急情况,接受者可以选择优先处理)

    • ACK:应答

    • PSH:推送数据(接收方应该尽快将这个报文段交给应用层)

    • RST:连接重置(遇到该状态码,代表你的连接已非常混乱,一般应用层会收到一个连接重置异常)

    • SYN:建立连接

    • FIN:结束

  • 窗口大小:用于流量控制(窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接受的字节)

  • 校验和:主要是检验数据的准确性

  • 紧急数据:当URG标志1时有效,发送端向另一端发送紧急数据

  • 可选字段:其他附件信息

由上可见呀,TCP协议中许多信息都是蕴含在TCP协议头里面,我们使用抓包工具抓包时,能分析统计到关于连接的情况都是根据头部信息得到的,对头部信息的掌握能快速让我们掌握TCP协议原理,对问题的定位我们能更深入层面的分析。

三、TCP连接的建立与终止

看完了TCP协议的基本信息介绍,我们老生常谈,继续来聊聊TCP的连接与断开问题,从连接断开的过程中我们能初步了解到TCP数据段的传输机制,与可靠性保证,首先,我们先来看看连接与断开的时序图。

在这里插入图片描述

1、连接建立协议

TCP的连接,仿佛就像男女之间建立美妙的爱情关系

男:我爱你
女:嗯,我也爱你
男:嗯

相互的询问,相互的确认,爱情就这样产生。TCP也不过如此

clientA:client端发送一个SYN段指明server端打算连接的server的端口,以及初始序号ISN
serverB:server发回包含server的初始序号SYN报文段作为应答。同时将确认序号设置为client的ISN+1以对客户端的SYN报文段进行确认。一个SYN将占用一个序号
clientA:client必须将确认序号设置为server的ISN+1以对服务器的SYN报文段确认

以上的过程,我们关注两个问题

关于初始ISN

ISN随时间而变化,是一个32bit的计数器,每4ms加1,这样的选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个链接的一方对它作错误的解释。

为什么需要三次握手?

这个问题其实真的没有那么复杂,根据上文,我们可以知道TCP的可靠性保障机制之一就是消息确认机制,你想想呀,如果是两次握手的话,那少了一次ACK,server怎么知道到底client是收到自己的SYN请求没呢?这样可靠性就得不到保证了。

2、连接断开协议

成年人的爱情就是龙卷风,来的快,走的快

女:对不起,我要跟你分手,我已经放下你了
男:嗯,我知道了

(男生并还没放下,男对女还是思念思念思念...)
(一段时间过去了,男生终于也放下了)

男:我也放下你了,我们就这样吧
女:嗯

相互的告别,相互的确认,当对方跟你告别时,你或许意犹未尽,终于等到你把最后一滴思念都给完了,那你也会跟她做最后的告别,一段感情到此为止。TCP也不过如此

clientA:向server发送一个FIN
serverB:发回一个ACK,ISN为收到的FIN的ISN+1
(serverB 继续把没发完的数据发发发,直到发完数据)
serverB:向client发送一个FIN
clientA:发回一个ACK,ISN为收到的FIN的ISN+1

这里我们需要关注一下这个问题:

为什么握手是三次、而挥手要四次?

这是由TCP的半关闭(half-close)造成的。既然一个TCP连接是全双工的,因此每个方向必须单独的进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向连接。当一端收到一个FIN,它必须通知应用层另一端已经终止了那个方向的数据传送。发送FIN通常是应用层进行关闭的结果。

  • 全双工:数据在两个方向能同时传递

在这里插入图片描述

3、TCP状态变迁图

3.1、TCP状态

TCP状态在百度上面找不到定义哈,说一下笔者的理解。TCP状态是TCP连接端在主动或被动做了某种操作后显示的状态,该状态可以展示某条连接当前的信息即此时该连接正在做的某种操作(正在连接、已连接、发送数据…),在Linux上,我们可以通过以下命令看到所有TCP连接的状态情况

ss -ta

3.2、为什么要掌握TCP状态?

对笔者来说,TCP状态主要还是便于做故障分析,假定几个场景场景

#当前服务器的负载
ss -ta|grep 'ESTABLISHED'|wc -l

#服务端CLOSE_WAIT堆积,应用层没对FIN做响应,导致连接数占满
ss -ta|grep 'CLOSE_WAIT'|wc -l

3.3、状态图与时序图

这个图真可以,有时候状态也会忘,多看看真会熟悉滴

在这里插入图片描述

在这里插入图片描述

3.4、几个关于TCP状态的问题

为什么要存在TIME_WAIT状态?

TIME_WAIT状态也称为2MSL等待状态。每个具体的TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最大时间。

  • 它可靠地实现TCP全双工连接的终止。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)
  • 允许老的重复分节在网络中消逝
  • 这TCP连接在2MSL等待期间,定义这个连接的socket不能再被使用

也就是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。

关于FIN_WAIT_2状态

只有当另一端的进程完成这个连接关闭,客户端才会从FIN_WAIT_2状态进入TIME_WAIT状态。这意味着我们client可能永远保持这个状态。另一端也将处于CLOSE_WAIT状态,并一直保持这个状态直到应用层决定进行关闭。

许多伯克利实现采用如下方式来防止这种在FIN_WAIT_2状态的无限等待。如果执行主动关闭的应用层将进行全关闭,而不是半关闭来说明它还想接受数据,就设置一个定时器。如果这个连接空闲10min75s ,TCP 将进入CLOSED状态。

4、其他与连接相关的知识

最大报文段长度(MSS)是什么?

我们在上面的交互图中可以看到当发起连接时,双方都会把自己的MSS告诉对方,表示TCP传送另一端的最大块的数据长度。

同一时间发送的段=滑动窗口/MSS。

重视复位报文段RST

一般来说,无论如何一个报文段发往基准的连接出现什么错误,TCP都会发出一个报文段,一般来说可能会有以下场景

  • 到不存在的端口的连接请求
  • 终止一个异常连接
  • 检测半打开的连接
  • 连接被异常终止

TCP可否同时打开/同时关闭?

TCP是特意设计为了可以处理同时打开,对于同时打开它仅建立一条连接而不是两条连接。TCP协议也允许这样的同时关闭。

TCP选项的作用?

TCP选项,是包含在TCP头部里面一些其他的相关信息。如最大报文段长度、窗口扩大因子、时间戳等。

TCP服务器端程序设计是怎样的,socket?

当一个新的连接请求到达服务器时,服务器接收这个请求,并调用一个新进程来处理这个新的客户请求。不同操作系统使用不同的技术来调用新的服务器进程。在这个服务程序中,我们关注一下

  • TCP服务器端口号:只有处于LISTEN的进程能够接受新的连接请求。处于ESTABLISHD的进程不能接受SYN报文段。

  • 连接限制:可限定本地IP地址、远端IP地址

  • 呼入请求队列(划重点):到达多个连接请求,但是服务器正忙,并无法创建线程或进程去满足它,那么把这个连接丢入这个队列(backlog),不止一次在中间件调优中看到该参数(参见Redis),队列使用的规则

    • 正等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已被TCP接受,但还没被应用层所接受。注意区分TCP接受一个连接是将其放入这个队列,而应用层接受连接是将其从该队列中移除。
    • 应用层将指明该队列的最大长度,这个值通常称为积压值(backlog)
    • 当一个连接请求到达时,TCP使用一个算法,根据当前连接队列中的连接数来确定是否接受这个连接。我们期望应用层说明的积压值为这一端点所能允许接受连接的最大数目。
    • 如果对于新的连接请求,该TCP监听的端点的连接队列中海油空间,TCP模块将对SYN进行确认并完成连接的建立。但应用层只有在三次握手中的第三个报文段收到后才会知道这个新链接。另外,当客户进程的主动打开成功但服务器的应用层还不知道这个新的连接时,它可能会以为服务器进程已经准备好接受数据了(如果发生这种情况,服务器的TCP仅将接受的数据放入缓冲队列)
    • 如果对于新的连接请求,连接队列中没有空间,TCP将不会理会收到的SYN。也不发回任何报文段。如果应用层不能及时接受已被TCP接受的链接,这些连接可能占满整个连接队列,客户的主动打开最终将超时

四、数据交互规则

这一章节是一个小章节,主要讲一下玉数据交换有关的规则,主要是ACK的延迟确认、Nagle算法、窗口大小的通告

1、ACK的延迟确认

在经典书籍翻译是经受时延的确认,什么意思呢?指的是通常TCP在接收到数据时并不立即发送ACK;相反,它会延迟发送,以便将ACK与需要沿该方向发送的数据一起发送。绝大多数实现采用的时延为200ms,也就是说,TCP将以最大200ms的时延等待是否有数据一起发送。

2、Nagle算法

该算法要求一个TCP连接上最多只能一个未被确认的未完成小分组,在该分组的确认到达之前不能发送其他的小分组。相反,TCP收集这些少量的分组,并在确认到来时以一个分组的方式发送出去。该算法的优越之处在于它是自适应的:确认到达的越快,数据也就发送的越快。而在希望减少微小分组数目的低速广域网上,则会发送更少的分组。下图是在xshell上面的Nagle选项

在这里插入图片描述

当我们关闭Nagle算法时,可以让小消息必须无延时的发送,以便为进行某种操作的交互用户提供实时的反馈

3、通告窗口大小

TCP都在每个数据包上面向对方通告自己当前能处理的窗口大小,便于发送方以最优的策略发送数据包

五、TCP成块的数据流

这一章的名字听着很抽象,其实讲的就是滑动窗口协议。TCP以一个段为单位,每发一个段进行一次确认应答处理,这样的传输方式有一个缺点。那就是,包的往返时间越长通信性能就越低。

为了解决这个问题,TCP引入了窗口的概念。即使在往返时间较长的情况下,它也能控制网络性能的下降,确认的应答不再是以每个分段,而是以更大的单位进行确认时,转发时间将会被大幅度缩短。也就是说,发送端主机,在发送了一个段以后不必要一直等待确认应答,而是继续发送。还记得我们之前说的MSS吗?每一次的数据包大小不能超过MSS,每一波数据大小不能超过接收方的接收窗口大小。

在这里插入图片描述

1、滑动窗口

滑动窗口协议(Sliding Window Protocol),属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输,提高网络吞吐量。其单位为字节。

接下里,我们先看看看滑动窗口的可视化视图,掌握了这个可视化图,我们能更好理解滑动窗口的滑动二字意义在哪里,是如何控制数据包传输的

在这里插入图片描述

  • 提供的窗口:接收方通告的窗口,它覆盖了从第4字节到第9字节的区域
  • 当接收方确认数据后,这个滑动窗口不时地向右移动。窗口两边边沿的相对运动增加或减少了窗口的大小

再接下来看看窗口的状态变化

在这里插入图片描述

  • 窗口合拢:窗口左边向右边沿靠近。这种现象发生在数据被发送和确认时。
  • 窗口张开:窗口有边沿向右移动时将允许发送更多的数据。这种现象发生在另一端的接受进程读取已经确认的数据并释放了TCP的接收缓存时。
  • 如果左边沿到达有边沿:则称其为一个0窗口(接收方处理不过来了)
  • 窗口收缩:好像没有这种情况,不解释

虽然看完上面的视角图,你可能会有些疑惑,我汇总了一次请求的数据交换与窗口的变化图,仔细一品,感受滑动窗口的运作机制。

在这里插入图片描述

这其中

  • 发送方不必发送一个全窗口大小的数据
  • 来自接收方的一个报文段确认数据并把窗口向右边移动。这是因为窗口的大小是相对于确认序号的
  • 窗口的大小可以减小
  • 接收方在发送一个ACK前不必等待窗口被填满

2、接收方通告的窗口大小问题

  • 由接收方提供的窗口大小通常可以由接收进程控制,这将影响TCP的性能
  • socket API 允许进程设置发送和接收的缓存的大小。接收缓存的大小是该连接上所能够通过的最大窗口大小。有一些应用程序通过修改插口缓存大小来增加性能

3、PUSH标志

发送方使用该标志通知接收方将所收到的数据全部提交给接收进程。这里的数据包括与PUSH一起传送的数据以及接收方TCP已经为接收进程收到的其他数据

4、什么是慢启动?

有了TCP的窗口控制,收发主机之间即使不再以一个数据段为单位发送确认应答,也能够发送大量数据包。然而,如果在通信刚开始时就发送大量数据,也可能会引起其他问题。

一般来说,在网络出现拥堵时,如果突然发送一个较大量的数据,极有可能会导致整个网络瘫痪。故有了慢启动的过程。

慢启动为发送方的TCP增加了另一个窗口:拥塞窗口(congestion window),记为cwnd。当与另一个网络的主机建立TCP连接时,拥塞窗口被初始化为1个报文段(即另一端通告的报文段大小)。每收到一个ACK,拥塞窗口就增加一个报文段(cwnd以字节为单位,但是慢启动以报文段大小为单位进行增加)。发送方取拥塞窗口与通告窗口中的最小值作为发送上限。拥塞窗口是发送方使用的流量限制,而通告窗口则是接受方使用的流量限制。

在这里插入图片描述

在这里插入图片描述

发送方开始时发送一个报文段,然后等待ACK。当收到该ACK时,拥塞窗口从1增加为2,即可以发送两个报文段。当收到这两个报文段的ACK时,拥塞窗口就增加位4。这是一种指数增加的关系。

5、紧急窗口

还记得TCP头中的URG字段吗?它使一端可以告诉另一端有些具有某种方式的“紧急数据”已经放置在普通的数据流中。另一端被通知这个紧急数据已被放置在普通数据流中,由接收方决定如何处理。

可以通过设置TCP首部中的两个字段来发出这种从一端到另一端的紧急数据已经被放置在数据流中的通知。URG bit 被置为1,并且一个16 bit的紧急指针被置为一个正的偏移量,该偏移量必须与TCP首部中的序号字段相加,以便得出紧急数据的最后一个字节的序号。

如Telnet 和 Rlogin。当交互用户键入中断键时,或FTP当交互用户放弃一个文件传输时。

六、TCP的超时与重传

1、拥塞避免

根据上文的确认机制我们可以知道,慢启动是呈现指数级上涨的,速度是非常快的,但是如果接收方接收方处理不过来,或者是大家都因为速度太快发生网络拥堵的话,那快的意义就没有了,所以呀,TCP需要在慢启动一定的时间后,慢下来,我们称它为拥塞避免算法
但是这个拥塞避免算法是广义的一个过程,包含了慢启动的过程,又包含了快重传快恢复超时重传还有拥塞避免算法(这里指的是真正的一个算法,而不是过程)过程,以下算法过程是从经典书中摘录,结合图,好好过两遍,悟到了整个过程你就懂了。

在这里插入图片描述

  • 拥塞避免算法是一种处理丢失分组的方法。
  • 该算法假定由于分组受到损坏引起的丢失是非常少的,因此分组丢失就意味着源主机和目的主机之间的某处网络上发生了拥塞。有两种分组丢失的指示:发生超时和接收到重复的确认。
  • 拥塞避免算法和慢启动算法是两个目的不同、独立的算法。但是当拥塞发生时,我们希望降低分组进入网络的传输速率,于是可以调用慢启动来做到这一点。在实际中这两个算法通常在一起实现。

在这里插入图片描述
拥塞避免算法过程

  • 拥塞避免算法和慢启动算法需要对每个连接维持两个变量

    • 一个拥塞窗口cwnd
    • 一个慢启动门限ssthresh
  • 对一个给定的连接

    • 初始化cwnd为1个报文段
    • ssthresh为65535个字节
  • TCP的输出

    • 不能超过cwnd
    • 不能超过接收方通告窗口的大小
  • 当拥塞发生时(超时或收到重复确认)

    • ssthresh被设置为当前窗口大小(cwnd和接收方通过窗口大小的最小值)的一半(但最少为2个报文段),见下文的快速重传与快速恢复
    • 此外,如果是超时引起了拥塞,则cwnd被设置为1个报文段,然后进入慢启动过程, 你可以认为如果遇到超时,那您就重头来吧
  • 当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免

    • 如果cwnd小于或等于ssthresh,则正在进行的是慢启动,慢启动一直持续到我们回到当拥塞发生时所处位置的一半的时候才停止,然后转为执行拥塞避免。
    • 否则正在进行拥塞避免。拥塞避免算法要求每次收到一个确认时将 c w n d增加1 /c w n d。与慢启动的指数增加比起来,这是一种加性增长(additive increase)。我们希望在一个往返时间内最多为 c w n d增加1个报文段(不管在这个RT T中收到了多少个ACK),然而慢启动将根据这个往返时间中所收到的确认的个数增加cwnd

2、快速重传与快速恢复

从上文的拥塞避免算法中我们可以看到,当3次重复收到ACK的时候,代表网络堵塞,有丢包的现象产生,所以TCP会降低速度,并重传其报文段。

  • 快速重传:当重复收到三个重复ACK时,我们就重传丢失的数据报文段,而无须等待超时定时器溢出。

  • 快速恢复:当快速重传后,立刻执行拥塞避免算法,即是快速恢复。

算法执行过程

  • 当收到3个重复ACK时,将ssrhresh设置为当前拥塞窗口cwnd的一半。重传丢失的报文段。设置cwnd为ssthresh加上3倍报文段的大小
  • 每次收到另一个重复的ACK时,cwnd增加一个报文段大小并发送一个分组(如果新的cwnd允许发送)
  • 当下一个确认新数据的ACK到达时,设置cwnd为ssthresh。这个ACK应该是在进行重传后的一个往返时间内对步骤1中重传确认。另外,这个ACK也应该是对丢失的分组和收到的第1个重复ACK之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时我们将当前的速率减半

为什么一定要是三个重复ACK才会触发快速重传?

假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的ACK之前,只可能产生1~2个重复的ACK。如果一连串收到3个或3个以上的重复ACK,就非常可能是一个报文段丢失了。

重新分组

当TCP超时并重传时,它不一定要重传同样的报文段。相反,TCP允许进行重新分组而发送一个较大的报文段,这将有助于提高性能。

七、TCP的坚持定时器

这一章开始,我们了解一些周边的小知识。

什么是坚持定时器?

当客户端被通告窗口为0时,客户端将停止发送数据。会引起客户设置其坚持定时器。如果该定时器时间到时客户还没有接收到一个窗口更新,它就探查这个空的窗口更新是否丢失。

计算坚持定时器时使用了普通的TCP指数退避。窗口探查包含一个字节,但是所返回的窗口为0的ACK并不是确认该字节,因此这个字节被持续重传。

坚持状态与重传超时之间的不同是TCP从不放弃发送窗口探查。这些探查每隔60s发送一次,这个过程将持续到或者窗口被打开,或者应用进程使用的连接被终止。

糊涂窗口综合症

指的是少量的数据将通过连接进行交换,而不是满长度的报文段

故障可能发生的原因

  • 接收方通告一个小的窗口
  • 发送少量的数据

避免措施

  • 接收方不通告小窗口
  • 发送方满足这几种条件之一才发送数据
    • 可以发送一个满长度的报文段
    • 可以发送知识是接收方通告大小一半的报文段
    • 可以发送任何数据并且不希望接受ACK或者该连接上不能使用Nagle算法

八、TCP的保活定时器

保活定时器,主要是保持TCP连接的,比如你经常遇到的JDBC线程池,里面就有一个保活的概念。TCP是一条虚拟的链路,虽然通信双方进行握手建立虚拟通道,但是建立通道后如果不发生数据交互的话,那双方都不知道对方是不是还保持socket会与自己继续通讯,所以有了这个保活定时器。这也解决了之前疑惑的TCP连接的保活问题了。

通常是由服务器端设置这个功能

算法描述

  • 如果一个给定连接在两个小时之内没有任何动作,则服务器就向客户发送一个探查报文段
  • 客户主机状态
    • 客户主机依然正常运行
    • 客户主机已经崩溃
    • 客户主机已经崩溃并已经重新启动
    • 客户主机正常运行,但是从服务器不可达

九、TCP的未来和性能

TCP协议在草案中定义的窗口大小最大为65535bit,那是当时的网络情况比较差,这个窗口大小已经够用了。现在可是5G时代65535算个啥,所以呀,TCP就在头中的选项做了对窗口大小的扩展,以适应快速的网络环境。
至于时间戳选项就没得说了,用于计算包的往返时间,在wireshare给你展示包的发送时间,也是美美的。

  • 窗口扩大选项:通过定义一个选项实现对 16 bit的扩大操作 ( s c a l i n g o p e r a t i o n )来完成的。于是T C P在内部将实际的窗口大小维持为32 bit的值
  • 时间戳选项:时间戳选项使发送方在每个报文段中放置一个时间戳值。接收方在确认中返回这个数值,
    从而允许发送方为每一个收到的 A C K计算RT T

全文总结:之前对于TCP是陌生又熟悉,有了整套知识架构的支撑后,现在排查问题的过程中都觉得自信满满的,文章始终无法深入介绍TCP的完整知识,希望本文能基于你帮助,后面继续深入看书+tcpdum+wireshark,我深信你终能吃透TCP
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196926.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号