Linux网络编程——深入理解TCP的可靠性、滑动窗口、流量控制、拥塞控制
目录
一、前言
二、流量控制
三、TCP的滑动窗口
1、原理
2、机制
3、数据重发
Ⅰ、只是确认应答包(ACK)丢了
Ⅱ、发送数据包丢失
4、缓冲区结构
四、TCP的拥塞控制
1、慢启动
2、拥塞避免
3、快速重传
4、快速恢复
五、延迟应答
六、捎带应答
七、再谈TCP的面向字节流
粘包问题
一、前言
上篇文章中我们提到了TCP连接的可靠性,TCP为了这个可靠性做了很多的工作比如我们已经知道的
- 校验和
- 序列号,为了保证数据的按序到达等
- 确认应答
- 超时重发机制
- 连接管理
还有下面说的流量控制都是TCP为了传输可靠性而设计的。
二、流量控制
我们知道TCP连接的发送端和接收端都会存在着接收缓冲区和发送缓冲区,这些缓冲区的大小都是有限的,所以为了避免由于发送过快从而导致接收端的接收缓冲区被打满,引起丢包重传等一系列的连锁反应。发送端在发送连接请求之后,接受端将自己可以接收的缓冲区大小放入TCP报文中的 16位窗口大小 ,通过ACK通知发送端。
- 窗口字段大小越大,说明网络的吞吐量越高。
- 接收端一旦发现自己的缓冲区满了,就会将窗口设置成一个更小的值通知给发送端。发送端接收到之后,就会减缓它的发送速度。
- 如果接收端的 缓冲区满了,就会将窗口设置为0,这时发送端不再发送数据,但是需要定期发送一个窗口探测数据段,可以让接收端把窗口大小告诉发送端。
这16位数字最大的表示是65535,那么TCP窗口的最大字节就是65535字节吗?其实不是的,实际上,在TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是 窗口字段的值左移M 位。
除了TCP的可靠性,性能也是衡量传输的一个重要因素,TCP通过以下方式提高自己的性能
- 滑动窗口
- 快速重传
- 延迟应答
- 捎带应答
三、TCP的滑动窗口
我们已经知道了TCP的应答策略,对每一个发送的数据段,都要给一个ACK确认应答,等收到ACK确认之后再发送下一个数据段,但是这样有个问题就是效率太低,性能太差,尤其是在数据段在双方往返时间比较长的时候,如图所示
1、原理
那么我们可以采用一次性发送多条数据,这样就可以大大提高我们的性能,通过重叠多个数据段的传输与确认等待时间显著提升了传输效率。 如图所示
那如上图所示我们为什么不将1~4000的数据一起打包发送呢?这样不是更省事吗?实际上这样子是不行的,它的传输还跟底层有着关系,我们后面再详细说。
窗口大小指的是不需要等待确认应答而可以继续发送给数据包的最大值,上图的窗口大小就是4000个字节,即4个字段。
- 在发送前四个字段的时候,不需要等待任何的ACK,直接发送就好
- 收到第一个ACK之后,滑动窗口向后移动,继续发送第五个段的数据,以此类推
- 操作系统为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有确认应答过的数据才会从缓冲区中删掉
- 窗口越大,则网络的吞吐量越高
2、机制
我们该怎么理解滑动缓冲区呢?
事实上,滑动缓冲区就是TCP发送缓冲区中的一段动态的逻辑范围,用于控制哪些数据允许被发送或者保留。它并不需要占用额外的空间,仅仅通过左右边界来标记发送缓冲区中的数据状态。
- 左边界(已确认数据的末尾):决定了哪些数据可以移出缓冲区。
- 右边界(左边界+窗口大小):决定哪些数据允许被发送。
滑动窗口将发送缓冲区中的数据划分为了四块分别为:
- 已发送且已经确认(窗口外的数据):该部分数据已经被发送且已经被接收方确认(ACK),无需保留,缓冲区空间可释放,思考这是怎么释放的呢?
- 已发送但未确认(窗口内数据):该部分数据已经发送但是尚未收到ACK,需要保留以备重传
- 可以发送但是未发送(窗口内数据):当前窗口允许发送的数据但是尚未发送,发送方可立即传输
- 不可发送(窗口外的数据):这部分是窗口外的数据,需要等待窗口滑动才能进入可发送区域。
将来拷贝到发送缓冲区中的新数据就存放在右边的虚线部分中。
本质上就是该缓冲区是一个数组,所谓的窗口滑动问题就是数组的下标在更新。
那滑动窗口的大小怎么定呢?实际上滑动窗口的大小不仅受接收端接收缓冲区大小的影响,还受到其他影响(后面再说),我们先暂且认为滑动窗口的大小只和对方的接收区大小相关。即
Win_start=0
Win_end=Win_start+tcp_win
所以未来滑动窗口无论怎么滑动,都必须要保证对方能够正常接收。
滑动窗口机制原理如图所示,假设窗口大小是3
3、数据重发
在进行数据包传输时,难免会出现数据丢失情况。这种情况一般分为两种,下面主要分析滑动窗口遇到的这种情况
Ⅰ、只是确认应答包(ACK)丢了
- 发送端发送数据包(窗口大小为3):同时发送 3 个数据包 1-1000、1001-2000 和 2001-3000。
- 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。数据包 1-1000 和数据包 2001-3000 的确认应答包没有丢失,但是数据包 1001-2000 的确认应答包丢失了。
- 发送端第 2 次发送数据包:发送端收到接收端发来的确认应答包,虽然没有收到数据包 1001-2000 的确认应答包,但是收到了数据包 2001-3000 的确认应答包**(下一个是3001)**,于是判断第一次发送的 3 个数据包都成功到达了接收端。再次发送 3 个数据包 3001-4000、4001-5000 和 5001-6000。
- 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。数据包 3001-4000 和数据包 4001-5000 的确认应答包丢失了,但是数据包 5001-6000 没有丢失。
- 发送端第 3 次发送数据包:发送端收到接收端发来的确认应答包,查看到数据包 5001-6000 收到了确认应答包**(下一个是6001)**。于是判断第 2 次发送的 3 个数据包都成功到达了接收端。
由于序号是有序的,如果接收到后面数据的ACK,说明前面的数据已经被接收,只是发送的ACK丢包了。这种情况就表示前面的数据包已经成功被接收端接收了,发送端也就不需要重新发送前面的数据包了。这又体现了确认序号设计的高明性。
Ⅱ、发送数据包丢失
- 发送端发送数据包(窗口大小为3):同时发送 3个数据包,分别为 1-1000、1001-2000 和 2001-3000。
- 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。接收端收到了数据包 1-1000,返回了确认应答包;但是数据包 1001-2000,在发送过程中丢失了,没有成功到达接收端。数据包 2001-3000 没有丢失,成功到达了接收端,但是该数据包不是接收端应该接收的数据包,数据包 1001-2000 才是真正应该接收的数据包。因此收到数据包 2001-3000 以后,接收端第一次返回下一个是 1001 的确认应答包。
- 发送端发送数据包:发送端仍然继续向接收端发送 3个数据包,分别为 3001-4000、4001-5000 和 5001-6000。
- 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。当接收端收到数据包 3001-4000 时,发现不是自己应该接收的数据包 1001-2000,第二次返回下一个是 1001 的确认应答包。当接收端收到数据包 4001-5000 时,仍然发现不是自己应该接收的数据包 1001-2000,第三次返回**下一个是1001 的确认应答包。以此类推直到接收完所有数据包,接收端都返回下一个是1001 **的确认应答包。
- 发送端重发数据包:发送端连续 3 次收到接收端发来的**下一个是1001 **的确认应答包,认为数据包 1001-2000 丢失了,就进行重发该数据包。
- 接收端收到重发数据包:接收端收到重发数据包以后,查看这次是自己应该接收的数据包 1001-2000,并返回确认应答包,告诉发送端,下一个该接收 6001 的数据包了。
- 发送端发送数据包:发送端收到确认应答包后,继续发送窗口大小为 3的数据包,分别为 6001-7000、7001-8000 和8001-9000。
- 对于步骤6、7:由于之前2001-6000的数据接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中,所以直接发送6001开始的数据即可。
上面的机制也被称为“高速重发机制”(快重传)
4、缓冲区结构
讲到这里,我们已经对滑动窗口有了了解,还有一个问题,我们知道滑动窗口是不可能向左滑动的,那么一直向右滑动,总会有到头的一天,这该怎么办?
事实上,缓冲区的结构并不是我们上面给到的那么简单,它是一个环形结构,读指针右移(ACK到达)与写指针右移(新数据写入)共同实现“逻辑环状”效果。同时,还满足了高效的内存复用,已确认的数据需及时释放空间,供后续数据写入。对于想要删除的数据直接进行覆盖。
四、TCP的拥塞控制
我们上面提到的TCP的可靠性和高性能方面的设计都是基于客户端和服务端的,但是我们还忽略了一个重要的点,那就是数据传输的过程中是否也会出现问题呢?下面要讲到的就是网络过程中的问题。
尽管有了滑动窗口的设计我们在发送大量的数据时会有着很高的效率,但是倘若我们在一开始就发送大量的数据,仍有可能会引发问题。因为我们对当前的网络状态并不清楚,网络上存在着许许多多的计算机,如果当前网络已经比较拥堵,再贸然发送大量的数据,会出问题的。
TCP拥塞控制通过动态调整发送窗口来平衡网络吞吐量与拥塞风险,结合了慢启动、拥塞避免、快速重传、快速恢复
1、慢启动
所以TCP引入一种 慢启动机制,先发送少量的数据探探路,摸清楚当前的网络状态后,再决定按照多大的速率传输数据。
- 我们在这里先引入一个概念:拥塞窗口,注意这个概念没有体现在TCP的报头里
- 发送刚开始的时候,先初始化拥塞窗口的大小为1 MSS(最大报文段大小)
- 对于每次每收到一个ACK,就将拥塞窗口加一。(注意这是指数增长!!)
- 每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小作比较,取较小的值作为实际发送的窗口大小。也就是 滑动窗口大小=min(拥塞窗口,对端窗口),
上面的拥塞窗口的增长速度是指数级别的,虽然叫”慢启动“,但是是指刚开始慢,但是增长速度快。这是因为前期慢,是为了让它有一个启动的时间,一旦启动,就让它赶快传输数据。
2、拥塞避免
为了避免因拥塞窗口增长太快,导致传输速率过快从而使得网络堵塞。引入 慢启动阈值(ssthresh) 当拥塞窗口超过这个阈值的时候,便不再按照指数的方式增长,而是按照线性的方式增长。
- 当TCP启动的时候,慢启动的阈值等于窗口的最大值
- 在每次超时重发的时候,慢启动的阈值就会降为原来的一半,同时拥塞窗口重新置为1
3、快速重传
当接收端收到一个失序的报文段时,会立即发送重复确认(duplicate ACK)给发送端。如果发送端连续收到三个重复确认,就认为有报文段丢失,并立即重传该报文段,而无需等待超时定时器到期。
4、快速恢复
在快速重传后,发送端将ssthresh设置为当前拥塞窗口大小的一半,并将拥塞窗口设置为ssthresh加上3个报文段的大小。然后,每收到一个重复的确认,拥塞窗口就增加1个报文段的大小,并发送一个新的报文段。当下一个确认新数据的ACK到达时,拥塞窗口被设置为ssthresh,进入拥塞避免阶段。
总的流程就是:
- 慢开始、拥塞控制
- 快重传、快恢复
- 一切的基础还是慢开始,这种方法的思路是这样的:
- 发送方维持一个叫做“拥塞窗口”的变量,该变量和接收端口共同决定了发送者的发送窗口;
- 当主机开始发送数据时,避免一下子将大量字节注入到网络,造成或者增加拥塞,选择发送一个1字节的试探报文;
- 当收到第一个字节的数据的确认后,就发送2个字节的报文;
- 若再次收到2个字节的确认,则发送4个字节,依次递增2的指数级;
- 最后会达到一个提前预设的“慢开始门限”
上述方法的目的是在拥塞发生时循序减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。慢开始和拥塞控制算法常常作为一个整体使用,而快重传和快恢复则是为了减少因为拥塞导致的数据包丢失带来的重传时间,从而避免传递无用的数据到网络。快重传的机制是:
-1. 接收方建立这样的机制,如果一个包丢失,则对后续的包继续发送针对该包的重传请求;
-2. 一旦发送方接收到三个一样的确认,就知道该包之后出现了错误,立刻重传该包;
-3. 此时发送方开始执行“快恢复”算法:
*1. 慢开始门限减半;
*2. cwnd设为慢开始门限减半后的数值;
*3. 执行拥塞避免算法(高起点,线性增长);
五、延迟应答
我们知道窗口越大,吞吐量越大,传输的效率也就越高,我们要保证在网络不拥塞的情况下尽量提高数据传输效率。
- 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;
- 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
- 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
- 如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M
这就是延迟应答,那么所有的包都可以延迟应答么? 肯定也不是;也并不是所有的报文都需要应答的
- 数量限制: 每隔N个包就应答一次;
- 时间限制: 超过最大延迟时间就应答一次;
具体的数量和超时时间, 依操作系统不同也有差异; 一般N取2, 超时时间取200ms;是要小于重传时间的
六、捎带应答
在延迟应答的基础上, 我们发现, 很多情况下, 客户端服务器在应用层也是 "一发一收" 的. 意味着客户端给服务器说
了 "How are you", 服务器也会给客户端回一个 "Fine, thank you";
那么这个时候ACK就可以搭顺风车, 和服务器回应的 "Fine, thank you" 一起回给客户端。
比如我们在讲到TCP的四次挥手的时候,假设发送端给接收端发送FIN报文的时候,接收端此时恰好也想要断开连接,那么此时接收端就可以在发送确认ACK时顺带着FIN一起发过去,这时候就变成了”三次握手“
七、再谈TCP的面向字节流
创建一个TCP的socket, 同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区;
- 调用write时, 数据会先写入发送缓冲区中;
- 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出;
- 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去;
- 接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;
- 然后应用程序可以调用read从接收缓冲区拿数据;
- 另一方面, TCP的一个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工
由于缓冲区的存在, TCP程序的读和写不需要一一匹配, 例如:
写100个字节数据时, 可以调用一次write写100个字节, 也可以调用100次write, 每次写一个字节;读100个字节数据时, 也完全不需要考虑写的时候是怎么写的, 既可以一次read 100个字节, 也可以一次read一个字节, 重复100次;TCP是面向字节流的,不用管这些,这些是需要应用层自己管的。
粘包问题
- 首先要明确, 粘包问题中的 "包" , 是指的应用层的数据包.
- 在TCP的协议头中, 没有如同UDP一样的 "报文长度" 这样的字段, 但是有一个序号这样的字段.
- 站在传输层的角度, TCP是一个一个报文过来的. 按照序号排好序放在缓冲区中.
- 站在应用层的角度, 看到的只是一串连续的字节数据.
- 那么应用程序看到了这么一连串的字节数据, 就不知道从哪个部分开始到哪个部分, 是一个完整的应用层数据包
那么如何避免粘包呢?
- 对于定长的包, 保证每次都按固定大小读取即可; 例如上面的Request结构, 是固定大小的, 那么就从缓冲
- 区从头开始按sizeof(Request)依次读取即可;
- 对于变长的包, 可以在包头的位置, 约定一个包总长度的字段, 从而就知道了包的结束位置;
- 对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序猿自己来定的, 只要保证分隔符不和正文冲突就可以
UDP就没有上述的问题,因为它是面向数据报的,要么不收,要么全收,不会出现粘包问题。
上面就是关于TCP可靠性的所有内容了
感谢阅读!
相关文章:
Linux网络编程——深入理解TCP的可靠性、滑动窗口、流量控制、拥塞控制
目录 一、前言 二、流量控制 三、TCP的滑动窗口 1、原理 2、机制 3、数据重发 Ⅰ、只是确认应答包(ACK)丢了 Ⅱ、发送数据包丢失 4、缓冲区结构 四、TCP的拥塞控制 1、慢启动 2、拥塞避免 3、快速重传 4、快速恢复 五、延迟应答 六、捎带应答 七、再谈TCP的面…...
Manifold-IJ 2022.1.21 版本解析:IntelliJ IDEA 的 Java 增强插件指南
Manifold-IJ-2022.1.21 可能是 IntelliJ IDEA 的一个插件或相关版本,特别是与 Manifold 这个增强 Java 开发体验的框架相关的组件。 很多时候没有网络环境,而又需要这个插件。 Manifold-IJ 2022.1.21下载:https://pan.quark.cn/s/ad907344c…...
linux内核
一 初识linux内核 1.1操作系统和内核简介 操作系统的精确定义并没有一个统一的标准,这里我认为操作系统是指整个系统负责完成最基本功能和系统管理的那些部分 这些部分包括内核,设备驱动程序,启动引导程序,基本的文件管理工具和…...
基于CNN-LSTM-GRU的深度Q网络(Deep Q-Network,DQN)求解移动机器人路径规划,MATLAB代码
一、深度Q网络(Deep Q-Network,DQN)介绍 1、背景与动机 深度Q网络(DQN)是深度强化学习领域的里程碑算法,由DeepMind于2013年提出。它首次在 Atari 2600 游戏上实现了超越人类的表现,解决了传统…...
C++23新特性:显式对象形参与显式对象成员函数
文章目录 一、背景与动机二、语法与基本使用三、优势与应用场景(一)简化代码(二)提升模板编程灵活性(三)与Lambda表达式结合 四、限制与注意事项五、总结 C23标准引入了一项重要的语言特性——显式对象形参…...
leetcode_242. 有效的字母异位词_java
242. 有效的字母异位词https://leetcode.cn/problems/valid-anagram/ 1、题目 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词(字母异位词是通过重新排列不同单词或短语的字母而形成的单词或短语,并使用所有原字母一次…...
【Docker基础】容器技术详解:生命周期、命令与实战案例
文章目录 一、什么是容器?二、为什么需要容器三、容器的生命周期容器状态容器OOM容器异常退出容器异常退出容器暂停 四、容器命令命令清单详细介绍 五、容器操作案例容器的状态迁移容器批量操作容器交互模式attached 模式detached 模式interactive 模式 容器 与 宿主…...
电子电气架构 --- 为配备区域计算的下一代电子/电气(E/E)架构
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...
python基础:位置互换
n int(input()) for _ in range(n):line input().strip()line list(line)for i in range(1,len(line)1):if i%2 0:line[i-2], line[i-1] line[i-1],line[i-2] print(.join(line))以下分不同数据类型说明 Python 实现奇偶互换的方法: 字符串的奇偶位互换 若字…...
51单片机Day03---让一个LED灯闪烁
目录 1.研究原理图: 2.一些小知识(重定义的使用): (1)在单片机中,unsigned int 常用于以下场景: (2)unsigned char: 3.思路构造:…...
城电科技 | 从概念到落地:如何打造真正的智慧零碳园区?
在科技飞速发展的当下,智慧零碳园区成为了引领未来发展的重要范式。那么,究竟什么是智慧零碳园区呢? 智慧零碳园区,是借助前沿信息技术,把物联网、云计算、大数据等技术深度融入园区管理及产业运营,以此达…...
oracle常见问题处理集锦
oracle常见问题处理集锦 oracle常见问题处理集锦ORA:28000 the count is locked oracle常见问题处理集锦 ORA:28000 the count is locked ORA-28000: 账户已被锁定 这个错误表示你尝试登录的 Oracle 数据库用户账户已被锁定,常见原因包括: 多次密码输错…...
Java-JDBC入门程序、预编译SQL
一. JDBC JDBC:Java DataBase Connectivity 就是使用Java语言操作关系型数据库的一套API 本质:sun公司官方定义一套操作所有关系型数据库的规范,即接口;各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使…...
【SQL】基于多源SQL 去重方法对比 -- 精华版
【SQL】基于SQL 去重方法对比 -- 精华版 一、引言二、基于SQL去重方法完整对比1. MySQL去重方法及优劣势1.1 DISTINCT关键字1.2 GROUP BY子句1.3 UNION系列操作1.4 子查询 自关联 2. Hive去重方法及优劣势2.1 DISTINCT关键字2.2 GROUP BY子句2.3 ROW_NUMBER窗口函数2.4 …...
list的使用以及模拟实现
本章目标 1.list的使用 2.list的模拟实现 1.list的使用 在stl中list是一个链表,并且是一个双向带头循环链表,这种结构的链表是最优结构. 因为它的实现上也是一块线性空间,它的使用上是与string和vector类似的.但相对的因为底层物理结构上它并不像vector是线性连续的,它并没有…...
java继承练习
//创建父类public class Employee {private String id;private String name;private double salary;public Employee() {}public Employee(String id, String name, double salary) {this.id id;this.name name;this.salary salary;}public String getId() {return id;}pu…...
猫咪如厕检测与分类识别系统系列【一】 功能需求分析及猫咪分类特征提取
开发背景 家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的…...
sparkcore编程算子
今天是Spark Core编程算子 Value类型算子 1. map 将处理的数据逐条进行映射转换,这里的转换可以是类型的转换,也可以是值的转换。Map算子是分区内一个数据一个数据的执行,类似于串行操作。 特点: - 主要目的将数据源中的数据进行…...
【EI会议】第三届机器人与软件工程前沿国际会议(FRSE 2025)
第三届机器人与软件工程前沿国际会议(FRSE 2025)将于2025年8月8日-10日在中国张家界召开。会议由清华大学自动化系主办,长沙理工大学、湖南科技大学、吉首大学、AC学术中心协办。 一、会议信息 大会官网:www.icfrse.org 会议时…...
机器人系统仿真--1.机器人模型URDF
添加机器人地盘...
具身机器人中AI(DEEPSEEK)与PLC、驱动器协同发展研究:突破数据困境与指令精确控制(3)
具身机器人中AI(DEEPSEEK)与PLC、驱动器协同发展研究:突破数据困境与指令精确控制(1)-CSDN博客 具身机器人中AI(DEEPSEEK)与PLC、驱动器协同发展研究:突破数据困境与指令精确控制&a…...
+++++背到厌倦。持续更新
Spring IoC 的工作流程: 读取 BeanDefinition: Spring 容器启动时,会读取 Bean 的配置信息 (例如 XML 配置文件、注解或 Java 代码),并将这些配置信息转换为 BeanDefinition 对象。创建 Bean 实例: 根据 BeanDefinition 中的信息,Spring 容器…...
修改 docker 工作目录
一、停掉 containerd、cri-docker、docker systemctl stop containerd systemctl stop cri-docker systemctl stop docker 二、拷贝 docker 工作目录下的所有文件到新路径 rsync -aP /var/lib/docker/ /docker/data/ 三、daemon.json 添加新工作目录路径 {"registry-…...
51c嵌入式~继电器~合集1
我自己的原文哦~ https://blog.51cto.com/whaosoft/13775821 一、继电器应用细节 继电器的应用,相信大家都知道,在电路中只要给它供电、断电也就可以工作了。本文讨论它的应用细节。 现在流行的接法 图中,继电器的线圈经过Q1作为开关&am…...
舵机:机器人领域的“关节革命者”
机器人的技术,每一个细微的进步都可能引领一场行业变革。而在这场变革中,舵机作为机器人关节的核心部件,正悄然上演着一场革命性的应用风暴。从简单的关节运动到复杂的姿态控制,舵机以其卓越的性能和无限的可能,重新定…...
飞书集成衡石ChatBot实战:如何10分钟搭建一个业务数据问答机器人?
让数据查询像聊天一样简单 在快节奏的业务环境中,数据查询的实时性和便捷性至关重要。传统BI工具需要复杂的操作,而衡石ChatBot结合飞书,让业务人员只需在聊天窗口提问,就能立刻获取数据反馈,真正实现“零门槛”数据分…...
高并发环境下超发现象的详细分析,包含场景示例、影响分析及解决方案(悲观锁、乐观锁、分布式锁)
以下是针对高并发环境下超发现象的详细分析,包含场景示例、影响分析及解决方案: 高并发下的超发详解 1. 超发现象定义 超发(Over-issuance)指在并发操作中,系统实际发放的资源(如商品库存)超过…...
Git 分支整合策略:Cherry-pick、Merge、Rebase 三者之间对比
Git 分支整合策略详解:Cherry-pick、Merge、Rebase 在日常的 Git 多分支协作开发中,代码合并是常见操作。Git 中主要提供以下三种方式来合并或迁移分支的提交: Cherry-pick:精确挑选部分提交复制到当前分支;Merge&am…...
嵌入式八股---计算机网络篇
前言 这块主要是结合着LWIP去理解计算机网络中常见的面试题 OSI四层/五层/七层模型 OSI分层(7层):物理层、数据链路层、网络层、传输层、会话层(http)、表示层(加密)、应用层。 TCP/IP分层(4层):网络接口层…...
使用 3D Layout 和 Icepak 进行 PCB、DCIR 和热分析
在本教程中,您将学习如何使用 3D Layout 执行 DCIR,然后使用功率损耗数据执行热分析。热分析将使用电子桌面 Icepak 进行。SIwave 及其嵌入式 icepak 可用于执行相同的分析,但有一个例外。电子桌面 Icepak 是一款功能齐全的 3D 工具。用户可以…...
UE5 Windows游戏窗口置顶
参考资料:UE5 UE4 项目设置全局置顶_ue4运行设置置顶-CSDN博客 修改完build.cs后,关掉重新生成解决方案。(不然可能编译报错,在这卡了半个小时) 不知道怎么用C的,可以用这个 Topmost - Keep Editor/Game w…...
【Linux】进程管理
一、程序与进程区别 1.程序: 存放在磁盘文件可执行文件(静态存在) 特点 静态性:程序是静态的,它只是一组指令的集合,在未被执行时,不会占用计算机的运行资源,也不会产生任何实际的…...
Android Studio PNG转SVG方法总结
在 Android Studio 中,将 PNG 位图转换为 SVG 矢量图并非直接内置的功能,但你可以通过以下步骤实现目标: 方法 1:使用在线转换工具 访问在线转换网站 推荐工具: CloudConvert Vector Magic OnlineConvertFree 上传…...
第6篇:Linux程序访问控制FPGA端LEDR<四>
Q:如何设计.c程序代码控制FPGA端外设LEDR动态显示? A:我们来设计程序实现简易计数器:将上一期点亮LEDR的程序代码*LEDR_ptr 0x2aa 改为 *LEDR_ptr *LEDR_ptr 1,读取LEDR端口的data寄存器,将寄存器值递增…...
DP扰码模块verilog仿真
在DisplayPort 1.4协议中,为了减少EMI,在8B/10B编码之前,需进行扰码Scramble。扰码用到了16-bit LFSR,表达式如下。 LFSR每移位8个bit后,用最高有效 8 位以相反的位顺序与一个字节数据进行异或从而实现数据加扰/解扰。…...
协作焊接机器人的应用场景
协作焊接机器人凭借其灵活性、安全性和高效性,在多个领域有着广泛的应用场景,以下是一些主要的方面: 汽车制造 车身焊接:在汽车车身生产线上,协作焊接机器人可与工人协同工作,完成车身各部件的焊接任务。例…...
深入解析计算机操作系统的底层架构与核心模块功能
深入解析计算机操作系统的底层架构与核心模块功能 一、操作系统底层架构总览 操作系统处于计算机系统的核心地位,是计算机硬件与用户之间的关键纽带,承担着资源管理者的重要角色。它负责统筹管理计算机的各类资源,如CPU、内存、存储设备以及…...
Elasticsearch 官网阅读学习笔记01
Elasticsearch 官网阅读学习笔记01 什么是 Elasticsearch? Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。Elasticsearch 可为所有类型的数据提供近乎实时的搜索和分析。无论您拥有的是结构化或非结构化文本、数值数据还是地理空间数据 Elastic…...
玩转Docker | 使用Docker搭建Van-Nav导航站
玩转Docker | 使用Docker搭建Van-Nav导航站 前言一、Van-Nav介绍van-nav 简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署Van-Nav服务下载镜像创建容器检查容器状态检查服务端口安全设置四、访问Van-Nav应用访问Van-Nav首页登录后台管理五、添…...
若依 前后端部署
后端:直接把代码从gitee上拉去到本地目录 (https://gitee.com/y_project/RuoYi-Vue ) 注意下redis连接时password改auth 后端启动成功 前端:运行前首先确保安装了node环境,随后执行: !!一定要用管理员权限…...
笔记:头文件与静态库的使用及组织方式
笔记:头文件与静态库的使用及组织方式 1. 头文件的作用 接口声明:提供函数、类、变量等标识符的声明,供其他模块调用。编译依赖:编译器需要头文件来验证函数调用和类型匹配。避免重复定义:通过包含保护(如…...
PostgreSQL-常用命令
PostgreSQL 提供了丰富的命令行工具和 SQL 命令,用于管理和操作数据库。以下是一些常用的命令和操作: 1. 数据库管理 创建数据库 CREATE DATABASE dbname; 删除数据库 DROP DATABASE dbname; 列出所有数据库 \l SELECT datname FROM pg_database;…...
如何在 Postman(测试工具) 中实现 Cookie 持久化并保持同一会话
在开发基于 Spring Boot 的 Web 应用时,使用 Session 存储验证码等敏感信息是常见的做法。然而,在调试接口时,你可能会遇到这样一个问题:第一次请求接口时存入的验证码在第二次请求时无法获取,原因往往是两个请求所使用…...
粘性定位(position:sticky)——微信小程序学习笔记
1. 简介 CSS 中的粘性定位(Sticky positioning)是一种特殊的定位方式,它可以使元素在滚动时保持在视窗的特定位置,类似于相对定位(relative),但当页面滚动到元素的位置时,它会表现得…...
谷歌浏览器极速安装指南
目录 📋 准备工作 步骤一:访问官网 🌐 步骤二:获取安装包 ⬇️ 步骤三:一键安装 🖱️ 步骤四:首次启动设置 ⚙️ 步骤五:开始探索! 🌟 💬 …...
【2024年最新IEEE Trans】模糊斜率熵Fuzzy Slope entropy及5种多尺度,应用于状态识别、故障诊断!
引言 2024年11月,研究者在测量领域国际顶级期刊《IEEE Transactions on Instrumentation and Measurement》(IF 5.6,JCR 1区,中科院二区)上发表科学研究成果,以“Optimized Fuzzy Slope Entropy: A Comple…...
无人机击落技术难点与要点分析!
一、技术难点 1. 目标探测与识别 小型化和低空飞行:现代无人机体积小、飞行高度低(尤其在城市或复杂地形中),雷达和光学传感器难以有效探测。 隐身技术:部分高端无人机采用吸波材料或低可探测设计,进…...
Flink的数据流图中的数据通道 StreamEdge 详解
本文从基础原理到代码层面逐步解释 Flink 的数据通道 StreamEdge,尽量让初学者也能理解。 主要思路:从概念开始,逐步深入到实现细节,并结合伪代码来逐步推导。 第一步:什么是 StreamEdge? StreamEdge 是 F…...
OpenCV 图形API(25)图像滤波-----均值滤波(模糊处理)函数blur()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 使用归一化的方框滤波器模糊图像。 该函数使用以下核来平滑图像: K 1 k s i z e . w i d t h k s i z e . h e i g h t [ 1 1 ⋯ …...
基于频率约束条件的最小惯量需求评估,包括频率变化率ROCOF约束和频率最低点约束matlab/simulink
基于频率约束条件的最小惯量评估,包括频率变化率ROCOF约束和频率最低点约束matlab/simulink 1建立了含新能源调频的频域仿真传函模型,虚拟惯量下垂控制 2基于构建的模型,考虑了不同调频系数,不同扰动情况下的系统最小惯量需求...