当前位置: 首页 > news >正文

TCP实现可靠传输的实现

TCP实现可靠传输的实现

目录

  • TCP实现可靠传输的实现
    • ARQ协议
      • 停止等待协议(古老)
      • 连续ARQ协议
        • 累计重传(回退N帧的ARQ协议)
        • 缓存确认(选择重传ARQ协议)
      • 超时重传的时间选择
    • TCP的流量控制
      • 零窗口探测报文段
      • Nagle算法
    • TCP的拥塞控制
      • TCP的拥塞控制方法
      • 路由器主动队列管理AQM
    • 参考

ARQ协议

为了方便表示我们在本小节中将A叫做发送方,而B叫做接收方

停止等待协议(古老)

停止等待就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。这其实就有点类似与半双工了。

停止等待协议的工作原理可以通过下图了解。

IMG_20230213_185732

理解停止等待协议只要根据上图看图说话就行。在无错误状态下A发送消息后在收到B返回的确认消息后再发出下一条消息。上图中的(b)则说明了若出现发送方报文出错重传的机制。下图展现了另外两种可能出现重传的情况。

IMG_20230213_185740

有一些细节需要注意:

  • A在发送完一个分组后,必须暂时保留已发送的分组的副本
  • 分组和确认分组都必须进行编号。这样才能明确时哪一个发送出去的分组收到了确认,而哪一个分组还没有收到确认。比如出现已失效的连接请求报文段
  • 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。需要考虑到网络中出现的时延和拥塞问题。

停止等待协议的优点是比较简单,但是信道利用率低

IMG_20230213_185748

根据上图我们,此时信道的利用率U可以粗略地通过下式来计算:
U=TDTD+RTT+TAU = \frac{T_D}{T_D + RTT + T_A} U=TD+RTT+TATD

连续ARQ协议

通过前面的介绍,我们可以知道停止等待协议的传输效率太低。我们可以想到用下图这种流水线的传输方式,显然这样可以提高信道的利用率。但是这也会带来新的问题,可以可以通过滑动窗口协议搭配不同的确认方式来解决

IMG_20230213_185805

累计重传(回退N帧的ARQ协议)

IMG_20230213_193629

滑动窗口协议限定了一次性发送数据的条数,同时限定了如何发送下一组请求。我们搭配着上面这副图来理解累计重传的原理。

例如,发送方一次性发送了5个分组,但是第二个分组丢失了。这个 时候接收方只能对第一个分组进行确认。发送方无法确认后面四个分组中还有哪个是传到了的,于是只好将后后面的四个分组全部重传。这也就出现了上图中滑动窗口向右滑动一个序号的原因,这就叫做Go-back-N(回退N)。

采用累计确认的方式时,接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认

通过这种多个重传的案例,可以清楚地知道连续ARQ在通信线路质量不好时带来的负面影响。

缓存确认(选择重传ARQ协议)

IMG_20230213_195916

我看别的很多都称这种方式为选择重传,但感觉根据自己的理解这个叫做缓存确认更容易理解。通过上图我们可以看到,在接收方可发送方分别需要维护一个发送缓存和一个接收缓存。

同样的我们对照着下图,来理解缓存确认的运作原理。例如,A已经发送了34-41分组中的数据,但是其中37、38、40都没有按照顺序被B收到。对于这三个未按序到达的数据而言可能是提早到、晚到、没传到。我举以下两个例子:

① 37、38、40 都提前到了

在数据提前到的时候,这些数据会先被B存放在自己的接收缓存中。当收到了36号数据后37、38依次接上并分别发送确认报文。40则在收到39后再接入。(如果过程中出现超时,也会触发A的重传)

②37没传到 38、40都提前到了

这个时候接收方最高发送的确认报文是36。而37号报文由于超时,A重新发送37这部分的数据,同时滑动窗口也会往后面移动,并发送42、43、44这三个序号的数据。

这里其实每次A收到确认号落在发送窗口内(考虑到“已失效的连接请求报文段”),那么A就可以使滑动窗口继续向前移动。

IMG_20230213_193746

发送缓存用来暂时存放:

  1. 发送应用程序传送给发送方TCP准备发送的数据
  2. TCP已发出但尚未收到确认的数据

接收缓存用来暂时存放:

  1. 按序到达的、但尚未被接受应用程序读取的数据
  2. 未按序到达的数据

根据前面的了解,我们需要注意以下三点:

  1. 虽然A的发送窗口是根据B的接收窗口设置的,但再同一时刻,A的发送窗口并不总是和B的接收窗口一样大(可以小于接收窗口)。
  2. 对于不按序到达的数据如何处理,TCP标准并无明确规定。如果接收方将不按序到达的数据一律丢弃,这样对网络资源的利用不利。因此TCP通常对不按序到达的数据先临时存放再接收窗口中,等到字节流中缺少字节收到后,再按序交付上层的应用程序
  3. TCP要求接收方必须有累计确认的功能,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送的时候把确认信息顺便捎带上。但TCP规定,确认的推迟时间不应超过0.5秒。

超时重传的时间选择

TCP采用了一种自适应算法,它记录了一个报文段发出的时间,以及收到相应的确认的时间(可以去看TCP尾部的选项字段)。这两个时间之差就是报文段的往返时间RTT。TCP保留了一个RTT的一个加权平均往返时间RTTs(也叫平滑的往返时间)。每当第一次测量到RTT样本值。但以后每测量到一个新的RTT样本,就按下式重新计算依次RTTs:
新的RTTs=(1−α)×(旧的RTTs)+α×(新的RTT样本)新的RTTs = (1 - \alpha) \times (旧的RTTs) + \alpha \times (新的RTT样本) 新的RTTs=(1α)×(旧的RTTs)+α×(新的RTT样本)
一般认为RTT样本值对新的RTTs的值影响较大,RFC 3298 推荐的α\alphaα值为0.125。**超时重传时间 RTO(Retransmission Time-Out)**应略大于上面得到的平滑RTTs。RFC 6298推荐使用下式计算RTO:
RTO=RTTs+4×RTTDRTO = RTTs + 4 \times RTT_D RTO=RTTs+4×RTTD
RTTDRTT_DRTTD是RTT的偏差的加权平均值,它与RTTs和新的RTT样本之差有关。
新的RTTD=(1−β)×(旧的RTTD)+β×∣RTTs−新的RTT样本∣新的RTT_D = (1 - \beta) \times (旧的RTT_D) + \beta \times|RTTs - 新的RTT样本| 新的RTTD=(1β)×(旧的RTTD)+β×RTTs新的RTT样本
这里的β\betaβ是一个小于1的系数,它的推荐值是0.25.

通过上面的公式我们就可以计算出重传时间RTO。但是我们在此时要考虑到超时重传时出现时:**如何判定此报文段时对先发送的报文段的确认,还是对后来重传报文段的确认?**由于重传的报文段和原来的报文段完全一样,因源主机在收到确认后,就无法做出正确的判断,而正确的判断对确定平均RTTs 的值关系很大,影响关系可以通过下图看出。

IMG_20230213_214431_edit_1767143973110561

于是又了Karn算法:在计算加权平均RTTS时,只要报文段重传了,就不采用其往返时间样本。这样就得出了加权平均RTTS和RTO就较准确。

但是若出现:报文段的时延突然增大很多。若不考虑重传的报文段重传时间,继续按照原来的RTO。将会导致出现大量的重传。

于是有了改进,方法是:报文段每重传依次,就把超时重传时间RTO增大一些(经典的做法是2倍)。当不再发生报文段的重传时,才根据RTO的计算公式计算超时重传。

TCP的流量控制

所谓的流量控制就是让发送方的速率不要太快,要让接收方来得及接收。(注意:流量控制是一种接收方对发送方来讲的机制,是一个端到端的问题)

利用滑动窗口机制可以比较方便地在TCP连接上实现对发送方的流量控制。

现在我们假定数据流向是单向的,也就是说发送方A只负责发送数据,不负责处理和接受数据,接收方B只负责处理和接收数据,并且对接收到的数据进行应答(ACK)。

在A和B建立连接的时候,B将自己的接收窗口RWND(receiver window)设置为400字节。这时候A将自己的发送窗口也设置为400,如下图所示。A给B连续发送了3个TCP报文段,每个报文段都包含100字节的数据,其中第三个TCP报文段因某种网络原因丢失。同时A收到了来自B的应答报文段,B调整接收窗口rwnd = 300。此时发送窗口应该是在301-500.于是A就继续发送301-400,401-500这两段报文。这时也触发了A201-300这段报文的超时重传。随后收到了对401-500这段报文的确认(这个时候说明前五段报文都已经被B收到了),并设置rwnd = 100。于是A根据rwnd再次调节发送窗口为100字节,此时发送窗口移动到了501-600的位置。在收到501-600这段报文后,根据rwnd = 0将发送窗口设置为0。

此时A需要等待B发送的新的接收窗口大小(rwnd > 0)才能继续发送数据。于是B向A发送更新自己rwnd的报文,但是意外出现了,这个更新报文段丢失,此时将会导致A在等待B的rwnd,B在等待A的新数据,于是出现了死锁局面

IMG_20230214_094326_edit_7980999840968

零窗口探测报文段

为了防止这种意外的发生,我们设置A在收到B的0接收窗口大小(rwnd=0)时会自动启动一个“持续计时器”,当持续计时器timeout时,如果还没有收到来自B的rwnd更新报文段,则会发送一个零窗口探测报文段(携带1字节数据),当B接收到这个TCP报文段后,会给A回复一个rwnd的更新,如果此时rwnd > 0,那么A就可以继续发送数据,如果rwnd=0,则重新启动一个持续计时器,重复上述步骤。

这也出现了另外一个问题糊涂窗口综合征:当B对应的交互式应用进程每次仅仅接收缓存中的1字节数据(这样使接收缓存空间仅腾出1字节),如果这个时候刚好收到了零窗口探测报文段,就会将rwnd设置为1,这样发送方就只能发送来1个字节的数据.这样进行下去,使网络的效率很低。

解决这个问题的方案是:

接受方等待一段时间,使得接收缓存已有足够空间容纳一个最长报文段MSS,或者等到接收缓存已有一般空闲空间。只要出现两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。

Nagle算法

为理解Nagle算法 ,我们可以设想以下场景:TCP的发送应用进程把要发送的数据逐字节地送到TCP发送缓存。这个时候为了提高网络的吞吐量,Nagle算法规定:

若应用进程把要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。Nagle算法还规定,当已到达发送缓存的数据已达到发送窗口的一半或已到达报文段的最大长度时,就立即发送一个报文段。

TCP的拥塞控制

在某段时间内,如果网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞。可以把出现网络拥塞的条件写成,如下式子:
∑对资源的需求>可用资源\sum 对资源的需求 > 可用资源 对资源的需求>可用资源
拥塞控制就是防止过多的数据注入到网络中,这样可用使网络中的路由器或链路不至于过载。拥塞控制是一个全局性的过程

IMG_20230214_111105_edit_12417588050708

  • 提供的负载 代表单位时间内输入给网络的分组数目。
  • 吞吐量 代表单位时间内从网络输出的分组数目

TCP的拥塞控制方法

TCP进行拥塞控制的算法有四种:慢开始拥塞避免快重传快恢复

下面考虑的拥塞窗口是基于滑动窗口协议的。发送发维护了一个**拥塞窗口cwnd(congestion window)**的状态变量。同时认为发送方超时计时器启动时,就判断网络出现拥塞。因为传输出差错而丢失分组的可能性比较小。

IMG_20230214_111630_edit_12504478549653

慢开始算法

慢开始就是由小到达逐渐增大注入网络中的数据字节,或者说是从小到大逐渐增大拥塞窗口数值。(RFC5861规定初始的cwnd设置为不超过2至4个)。

慢开始规定,在每收到一个对新报文段的确认后,可用把拥塞窗口增加最多一个SMSS的数值。为了避免cwnd过大,还需要设置一个慢开始门限 ssthresh

  • 当cwnd < ssthresh时,使用慢开始算法
  • 当cwnd > ssthresh时,使用拥塞避免算法
  • 当cwnd = ssthresh时,既可以使用慢开始算法,也可使用拥塞避免算法。

拥塞避免算法

拥塞避免算法就是让cwnd缓慢增大。执行算法的过程大概是这样的:每经过一个往返时间RTT,发送方的拥塞窗口cwnd的大小就增加1。拥塞避免并非完全避免拥塞,而是让拥塞窗口增长得缓慢一些。

快重传算法

在发现有分组丢失,认为网络出现了拥塞。如上图中的2号点。于是设置ssthresh = cwnd / 2、cwnd = 1。此时进入慢开始。在快重传算法中,接收方需要对发送方的数据立即做出确认,即使是失序且已接受的报文段也要做重复确认。如果发送方收到连续多条重复确认,发送方知道了只是丢失了个别报文段,于是开启快恢复

快恢复算法

使ssthresh = cwnd / 2,同时设置cwnd = ssthresh,并开始执行拥塞避免算法

路由器主动队列管理AQM

前面讨论的TCP拥塞控制并没有和网络层采取的策略联系起来。网络层的策略对TCP影响最大的就是路由器的分组丢弃策略。路由器会维护一个先进先出的队列,当队列已满,后续排队的分组都将被丢弃。这就叫做尾部丢弃策略

主动队列管理AQM(active Queue Management) 可用由不同的实现方法。其中**随机早期检验RED(Random Early Edtection)**是其中比较流行的。使用RED需要路由器维护两个参数:最小门限和最大门限。当每一个分组到达的时,RED就按照规定的算法先计算当前的平均队列的长度。并按照一下三种情况处理新的分组:

  1. 平均队列的长度 < 最小门限,则把新到的分组放入队列进行排队
  2. 平均队列的长度 > 最大门限,则把新到达的分组丢弃
  3. 最小门限 < 平均队列的长度 < 最大门限,按照一定的概率p,把新到达的分组丢弃(体现了分组丢弃的随机性)。

RED随机丢弃分组(对应第三种情况),是因为检测到网络拥塞的早期征兆。

参考

  • 《计算机网络 第7版》
  • 《计算机网络 第8版》
  • TCP的流量控制

相关文章:

TCP实现可靠传输的实现

TCP实现可靠传输的实现 目录TCP实现可靠传输的实现ARQ协议停止等待协议&#xff08;古老&#xff09;连续ARQ协议累计重传&#xff08;回退N帧的ARQ协议&#xff09;缓存确认&#xff08;选择重传ARQ协议&#xff09;超时重传的时间选择TCP的流量控制零窗口探测报文段Nagle算法…...

2/14考试总结

时间安排 7:30–7:50 看题,T1可能是个数据结构之类的东西&#xff0c;T2是 dp &#xff0c;T3 构造。 7:50–8:20 T3,仿照样例的构造&#xff0c;可以通过一部分测试点。 8:20–9:20 T1,发现题目实际上要求子树内各儿子的深度信息&#xff0c;可以 dsu &#xff0c;对于不能暴…...

程序环境和预处理详解

文章目录一、程序环境1.1 - 翻译环境1.1.1 - 编译1.1.1.1 - 预编译&#xff08;预处理&#xff09;1.1.1.2 - 编译1.1.1.3 - 汇编1.1.2 - 链接1.2 - 执行环境二、预处理详解2.1 - 预定义符号2.2 - #define2.2.1 - #define 定义标识符2.2.1.1 - 语法2.2.1.2 - 建议2.2.2 - #defi…...

The Social-Engineer Toolkit(社会工程学工具包)互联网第一篇全模块讲解

一、工具介绍 Social-Engineer Toolkit 是一个专为社会工程设计的开源渗透测试框架&#xff0c;可以帮助或辅助你完成二维码攻击、可插拔介质攻击、鱼叉攻击和水坑攻击等。SET 本身提供了大量攻击选项&#xff0c;可让您快速进行信任型攻击&#xff0c;也是一款高度自定义工具…...

Windows11去掉不满足系统要求的提示水印

我的电脑是LEGION的拯救者R70002021&#xff0c;预装的是Windows 11 家庭中文版&#xff0c;没有折腾重装过系统&#xff0c;今天突然注意到右下角出现了这个提示&#xff1a;“不满足系统要求。转到’设置"了解详细信息”。 在进入设置 - 系统 面板中也提示不满足系统要…...

JavaScript 计时事件

JavaScript 计时事件 通过使用 JavaScript&#xff0c;我们有能力做到在一个设定的时间间隔之后来执行代码&#xff0c;而不是在函数被调用后立即执行。我们称之为计时事件。 在 JavaScript 中使用计时事件是很容易的&#xff0c;两个关键方法是: setInterval() - 间隔指定的…...

七大排序算法的多语言代码实现

文章目录 前言 一、排序算法 1.原理简述 2.分类与复杂度 二、实例代码 1.冒泡排序 C Python Java Golang Rust Dephi 2.选择排序 C Python Java Golang Rust Dephi 3.插入排序 C Python Java Golang Rust Dephi 4.希尔排序 ​编辑 C Python Java Gola…...

【基础算法】表达式计算

中缀表达式:我们平常见到的正常数学式子 后缀表达式&#xff1a;12-3* 后缀表达式对于计算机很容易计算&#xff0c;只需要从头部扫描字符串。然后遇到数字就入栈&#xff0c;遇到运算符就取出栈顶的两个数进行运算。最后把运算结果入栈&#xff0c;最后栈中就会剩一个数为答…...

动态规划问题

目录 一、动态规划简介 二、利用动态规划解决问题 1、斐波拉契序列 2、拆分词句 3、三角形最小路径和 4、不同的路径数目&#xff08;一&#xff09; 5、带权值的最小路径和 6、求路径ii 7、01背包 8、不同子序列 9、编辑距离 10、分割回文串 一、动态规划…...

【MySQL进阶】 存储引擎 索引

&#x1f60a;&#x1f60a;作者简介&#x1f60a;&#x1f60a; &#xff1a; 大家好&#xff0c;我是南瓜籽&#xff0c;一个在校大二学生&#xff0c;我将会持续分享Java相关知识。 &#x1f389;&#x1f389;个人主页&#x1f389;&#x1f389; &#xff1a; 南瓜籽的主页…...

5 款最好的免费 SSD 数据恢复软件

SSD&#xff08;固态硬盘&#xff09;提供比传统硬盘更快的读/写速度&#xff0c;使启动、软件加载和游戏启动更快。因此&#xff0c;在我们选择存储设备时&#xff0c;它是一个极好的选择。但是&#xff0c;它仍然存在数据丢失的风险。假设您是受害者之一&#xff0c;正在寻找…...

MyBatis案例 | 使用映射配置文件实现CRUD操作——删除数据

本专栏主要是记录学习完JavaSE后学习JavaWeb部分的一些知识点总结以及遇到的一些问题等&#xff0c;如果刚开始学习Java的小伙伴可以点击下方连接查看专栏 本专栏地址&#xff1a;&#x1f525;JavaWeb Java入门篇&#xff1a; &#x1f525;Java基础学习篇 Java进阶学习篇&…...

CSDN 编程竞赛二十八期题解

竞赛总览 CSDN 编程竞赛二十八期&#xff1a;比赛详情 (csdn.net) 本期竞赛的题目都很简单&#xff0c;但是非常考验读题和编码速度。这一次没有遇到bug&#xff0c;竞赛体验较好。 竞赛题解 题目1、小Q的鲜榨柠檬汁 团建活动是大家所想要的。小Q给大家准备了鲜橙汁。现在…...

DML数据操纵语言

DML数据操纵语言 目录概述一、插入语句(一)方式一(二)方式二&#xff1a;(三)两种方式的比较二、修改语句三、删除语句概述方式一&#xff1a;delete方式二&#xff1a;truncate语句 【清空语句】delete VS truncate 【面试题&#xff01;&#xff01;&#xff01;】概述 数据…...

【Hello Linux】Linux工具介绍 (gcc/g++ gdb)

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍Linux的常用工具gcc/g 以及gbd Linux工具介绍gcc / ggcc / g的作用为什么语言要经过这四步才能变为可执行指令gcc / g语法预处理编…...

TeamFiltration:一款针对O365 AAD账号安全的测试框架

关于TeamFiltration TeamFiltration是一款针对O365 AAD账号安全的跨平台安全测试框架&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以轻松对O365 AAD账号进行枚举、喷射、过滤和后门植入等操作。TeamFiltering与CrackMapExec非常相似&#xff0c;它可以创建并维护一…...

你是真的“C”——Visual Studio 2022(VS2022)编译器 -—实用调试技巧

你是真的“C”——Visual Studio 2022&#xff08;VS2022&#xff09;编译器 -—实用调试技巧&#x1f60e;前言&#x1f64c;1. 什么是bug&#xff1f;&#x1f64c;2. 调试是什么&#xff1f;有多重要&#xff1f;&#x1f64c;2.1 调试是什么&#xff1f;2.2 调试的基本步骤…...

数据结构与算法:7种必须会的排序以及3种非基于比较排序

1.什么是排序 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序…...

数据库用户数

Oracle的用户数 oracle软件内部并没对用户数做限制&#xff0c;买5个用户数&#xff0c;指你买了5个user licences&#xff0c;从法律上只能连5个session&#xff0c;超过5个的连接都是非法的。oracle不给你技术上的限制&#xff0c;可是给你法律上的限制。 一般来讲&#xf…...

nginx如何用html显示多个图片并加入播放链接

需求背景通过nginx来做个点播服务&#xff0c;ffmpeg截取视频中的某一帧作为视频的封面&#xff0c;前端页面展示这个封面&#xff0c;&#xff0c;并链接到对应的视频播放链接&#xff0c;加载播放器进行播放简单介绍一下ffmpeg截取视频中的某一帧的方式截取视频的第一帧&…...

【蓝桥杯集训·每日一题】Acwing 3729. 改变数组元素

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴一维差分区间合并一、题目 1、原题链接 3729. 改变数组元素 2、题目描述 给定一个空数组 V 和一个整数数组 a1,a2,…,an。 现在要对数组 V 进行 n 次操作。 第 i 次操作的…...

springmvc执行流程

文章目录前言一、springMVC请求执行流程二、组件说明以下组件通常使用框架提供实现&#xff1a;总结前言 本篇文章是对springmvc的补充 接上篇文章springmvc入门https://blog.csdn.net/l_zl2021/article/details/127120873 一、springMVC请求执行流程 1.用户发送请求至前端控制…...

SpringMVC(2)

一)接受到JSON格式的数据:使用RequestBody来进行接收 ResponseBody表示的是返回一个非页面的数据 RequestBody表示的是后端要接受JSON格式的数据 一)接收单个格式的JSON格式的数据&#xff0c;我们使用一个对象来进行接收 1)我们之前接受GET请求中的queryString中的参数的时候&…...

Jackson序列化json时null转成空串或空对象

在项目中可能会遇到需要将null转""&#xff0c;可以通过以下方法解决。一&#xff1a;添加JacksonConfig 配置import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.databind.JsonSerializer;import com.fasterxml.jackson.databind.Objec…...

如何将Python的上级目录的文件导入?【from.import】

假如有如下目录&#xff1a; -python ----file1 ---------file1_1 ------------------pfile1_1.py ---------pfile1.py ----file2 ---------pfile2.py ----pfile.py ----data.py 在pfile1_1.py中想要将pfile.py 导入怎么办&#xff1f; 首先将其上级目录添加到系统目…...

Java实现碧蓝航线连续作战

目录一.实现功能二.主要思路三.代码实现四.用exe4j生成.exe程序五.最终效果六.代码开源一.实现功能 主线图作战结束到结算页自动点击再次前往 二.主要思路 判断是否进入了结算界面&#xff1a;记录结算界面某个像素点的RGB值&#xff0c;每隔3秒对这个像素点进行比对 移动鼠标…...

Docker笔记

文章目录1.docker为什么会出现2.docker是什么3.传统虚拟机和容器的对比3.1虚拟机3.2容器虚拟化技术3.3两者对比3.4为什么Docker会比VM虚拟机快&#xff1f;4.docker能干嘛6.docker的应用场景7.docker三要素一&#xff1a;镜像&#xff08;Image&#xff09;二&#xff1a;容器&…...

情人节使用AI TOOL来创建一个甜言蜜语的女伴

一、首先使用chatgpt生成一段情侣间的对话&#xff0c;需要反复几次&#xff0c;达到满意的程度&#xff0c;然后将女方的话归在一起。 这是一个情侣私下谈话的场景&#xff0c;女方表示对男朋友精心准备的情人节安排和礼物表示很满意 二、 打开网站&#xff1a;https://lexic…...

G-GhostNet(IJCV 2022)原理与代码解析

paper&#xff1a;GhostNets on Heterogeneous Devices via Cheap Operationscode&#xff1a;https://github.com/huawei-noah/Efficient-AI-Backbones/blob/master/g_ghost_pytorch/g_ghost_regnet.py前言本文提出了两种轻量网路&#xff0c;用于CPU端的C-GhostNet和用于GPU端…...

Ethercat系列(5)TWcat3激活过程的协议分析(续1)

顺序写系统时间偏移从-》主顺序写时间延迟主-》从从-》主顺序写分布式时钟启动主-》从从-》主读多重写系统时间主-》从从-》主顺序写应用层控制主-》从从-》主顺序读错误计数器主-》从从-》主顺序读应用层状态主-》从从-》主顺序读应用层&#xff0c;广播写错误计数器主-》从从…...