传输层协议TCP(上)

news2025/6/1 1:41:17

上一篇https://blog.csdn.net/Small_entreprene/article/details/148143494?fromshare=blogdetail&sharetype=blogdetail&sharerId=148143494&sharerefer=PC&sharesource=Small_entreprene&sharefrom=from_link


上文学习了传输层的协议之一UDP,接下来我们来好好学习一下传输层另外一个更加重要的协议 --- TCP协议:

TCP协议

TCP协议段格式 

tcphdr

struct tcphdr {
    __be16 source;       // 16位源端口号
    __be16 dest;         // 16位目的端口号
    __be32 seq;          // 32位序列号
    __be32 ack_seq;      // 32位确认号
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u16   res1:4,      // 保留位
            doff:4,      // TCP头长度,单位为4字节
            fin:1,       // FIN标志
            syn:1,       // SYN标志
            rst:1,       // RST标志
            psh:1,       // PSH标志
            ack:1,       // ACK标志
            urg:1,       // URG标志
            ece:1,       // ECE标志(用于拥塞控制)
            cwr:1;       // CWR标志(用于拥塞控制)
#elif defined(__BIG_ENDIAN_BITFIELD)
    __u16   doff:4,
            res1:4,
            cwr:1,
            ece:1,
            urg:1,
            ack:1,
            psh:1,
            rst:1,
            syn:1,
            fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
    __be16 window;       // 16位滑动窗口大小
    __sum16 check;       // 16位校验和
    __be16 urg_ptr;      // 16位紧急指针
};
标准问题 
TCP是如何实现将报头和有效载荷进行分离的?

前提说明:TCP设置为面向字节流,主要是为了其可靠性这个TCP的特性!!!

TCP协议的标准的报头的长度是20个字节,也就是一般而言,TCP报头也是一个定长的报头!也就是将来来一个TCP报文,我们只需要进行data指针位置的加20个字节,就可以提取出来了。不过TCP协议当中还有一个选项字段,可以为0字节,也可以有字节,这个后面我们自会理解!所以一个TCP报头的完整长度是20个字节加上选项字段,这个选项字段正常是为0字节的。因为有不定长的选项字段存在,我们该如何保证报文的报头和有效载荷进行分离呢?所以在标准报头20字节当中,存在一个叫做数据偏移的字段,也叫做4位首部长度,就是4个比特位,当成无符号来算,就是【0000,1111】总共是【0,15】个数据范围,TCP协议规定【0,15】的数据范围的单位是4字节,也就是说TCP报头的大小是【0,15*4】>>>【0,60】字节,但是对于TCP来说,其报头的标准长度最少都是20个字节,所以TCP的报头长度应该是x*4=20字节,也就是4位首部长度的范围应该是【0101,1111】,即【20,60】字节!

又因为TCP的报头的基本单位是4个字节,所以后面的TCP报头是肯定可以整除4个字节的【20,24,28,32,......,60】!所以将来选项的基本单位也是4字节的!!!

所以报头和有效载荷是如何进行分离的呢?就是我们首先无脑读取报文的前20个字节,然后提取4为首部长度,直接*4,然后减去20,剩下的就是选项的所占字节大小,最后剩下的就是有效载荷了! 

我们在谈UDP协议的报文格式的时候,UDP有其对应的报头长度8字节定长,其中报头中还有整个UDP报文的长度的,但是为什么TCP协议格式中为什么没有报文大小,只有报头大小呢? 没有对应的数据部分的长度?其实从这里我们就可以窥探出一个认知了:

在操作系统内部,操作系统可以知道UDP报文的边界的,知道UDP报文从哪里开始,从哪里结束,可以知道一个完整的UDP报文!因为UDP是面向数据报的!不过TCP是面向字节流的,在操作系统内部,发送了许多TCP数据段,他也区分不清楚是不是一个完整的报文,所以TCP不能够来表示一个报文完整的长度!

所以对于TCP协议来说,不需要,也不能设置一个叫做报文长度的字段,因为将来来的TCP报文是不是一个完整报文我操作系统吃不准!只能是将报头拿走,剩下的数据交给接收缓冲区当中,由用户上层自行去分析这么多个按序拼接好的有效载荷!

可是就不会说数据和下一个报头黏在一堆的情况嘛???

这种情况是不可能存在的,因为每收到一个报文,都是一个独立的sk_buff!!!

但是TCP是面向字节流的,报文的有效载荷在接收缓冲区当中会黏在一起!!!如果UDP有接收缓冲区,我们可以理解为数据报是由一个一个的队列维护的,这样就不会产生和字节流的黏在一起的问题了。 

TCP如何将自己的有效载荷交付给上一层?

当 TCP 数据段到达时,内核会根据目的端口号找到对应的套接字(socket),并将数据传递给该套接字关联的应用程序。这个过程是通过内核的协议栈和套接字管理机制实现的,确保数据能够准确地到达正确的应用程序。

可靠性的本质

确认应答(ACK)机制

给个实际的例子,两名同学在相距100m的操场上:

小B:吃了吗?

小S:吃了!

其实如果小S没有回复的话,那么小S可以看成是没有收到小B给小S发送的消息的!

但是小B回复了,也没办法确定说小N听到了,所以:

小S:好!

但是又这么保证说小N听到了呢?😥😥😥😥😥😥😥😥😥😥😥😥

所以这个世界上,在长距离传输的时候,根本就不存在100%可靠的协议!所以:

正确理解可靠性:

  • 具有应答,可以保证对历史消息的可靠性,是100%的:
  • 通信中,最新的报文,永远没有应答,最新可靠性无法保证!

TCP一般的通信过程(暂时这么说,后面会更加正确理解)(最朴素的认识)

在TCP当中,如果要保证可靠性,处于核心地位的可靠性,叫做确认应答机制!

就是在客户端和服务端,客户端向服务端发送消息,硬性规定说服务端要给客户端应答,这就是确定了客户端向服务端的可靠性;服务端向客户端发送消息,客户端响应服务端,给服务端做应答,这就保证说服务端到客户端的可靠性的保证:

不过这种模式是一个一个串行的走的,效率太低下了,所以我们就有了TCP传递信息时,更加通用的过程:

TCP传递信息时,更加通用的过程:

我们可以一次性发送多个报文,这就相当于是并行的由客户端向服务端发报文信息,这样的效率是明显提高了,但是一系列问题也就随之而来:

假设一次性发送过来的这么多报文数据当中,有其中一两条没有发送到服务端,服务端就没办法做应答,造成客户端没法接收到对应的应答!哪一个呢,客户端怎么知道!

所以为了能够更加细致的确认应答,TCP协议报头中就引入了32位序号和32位确认序号!

我们来好好说说:

假设客户端需要向服务端发送一系列数据包,每个数据包包含一个报文。为了提高效率,客户端选择一次性发送多个报文,而不是逐个发送。

客户端发送报文

客户端(C)一次性发送多个报文(黄色实线箭头)到服务端(S)。这些报文可能包含不同的数据,如请求、命令或数据更新。

服务端接收报文

服务端(S)接收到这些报文后,需要确认每个报文是否成功接收。服务端通过发送确认应答(绿色虚线箭头)来告知客户端哪些报文已经成功接收。

确认应答的作用

确认应答(绿色虚线箭头)包含一个确认序号,表示服务端期望接收的下一个字节的序号。例如,如果服务端成功接收了序号为1到10的报文,它会发送一个确认序号为11的应答。

客户端收到确认应答后,知道序号为1到10的报文已经被服务端成功接收,可以继续发送后续报文。(指定报文序号之前的所用信息,已经全部收到!!!---这个一条很重要的规定!!!

处理丢失的报文

如果服务端发现某个报文丢失(例如,序号为5的报文没有收到),它不会发送确认序号为6的应答,而是继续发送确认序号为5的应答,告知客户端需要重传序号为5的报文。

客户端收到这个重复的确认应答后,知道序号为5的报文丢失,需要重新发送该报文。

那么为什么会有两个序号,一个序号一个确认序号呢?

说人话:其实双方发送的是一个TCP报文,应答正常来说是TCP报头,总不能说客户端向服务器发送后,服务端只做应答,也就是报头,所以有捎带应答=报头+有效载荷,所以需要两个序号来,不然这么区分

详细说明:

在TCP协议中,数据传输的可靠性是通过序号和确认序号来保证的。这两个序号在TCP报文段中扮演着不同的角色:

1. 序号是用来标识TCP报文段中的数据字节流的位置。目的是为了确保数据的顺序性,允许接收方正确地重新组装从发送方接收到的数据片段。是标识本报文段的数据的第一个字节的序号。

2. 确认序号是用来指示接收方期望从发送方接收的下一个字节的序号。目的是为了告知发送方哪些数据已经被成功接收,从而触发发送方发送更多的数据或重传丢失的数据。如果ACK标志位被设置,此字段值加1即是下一个期望接收的字节序号。

TCP报文由TCP报头和可能的有效载荷(数据)组成。TCP报头包含了序号和确认序号等重要信息。

捎带应答(Piggybacking)

在TCP中,捎带应答是一种优化技术,它允许接收方在发送数据(即有数据要发送给发送方)时,将对先前接收数据的应答包含在同一个报文中。这样可以减少单独发送应答报文的次数,提高网络效率。(报头:确认应答+有效载荷:数据)(不是单单的只有报头,即只有单纯的应答!)

客户端发送数据:客户端发送一个TCP报文,序号为100,包含数据字节101到105。

服务端接收并发送数据:服务端接收到数据后,发送一个TCP报文作为应答,其中包含:

  • 确认序号:106(表示已成功接收到序号为105的数据,并期望接收下一个序号为106的数据)。

  • 有效载荷:如果服务端也有数据要发送给客户端,这些数据将作为有效载荷包含在同一个报文中。

为什么需要两个序号来区分?

  • 序号:用于标识发送的数据字节流,确保接收方可以正确地重新组装数据。

  • 确认序号:用于告知发送方哪些数据已经被成功接收,触发发送方的后续动作(如发送更多数据或重传丢失的数据)。

通过使用两个序号,TCP协议能够确保数据的可靠传输,同时通过捎带应答优化网络通信效率。这种设计允许TCP在保证数据完整性和顺序性的同时,也能够有效利用网络带宽。


好了,对应TCP,数据从发送端的发送缓冲区"拷贝"到对端的接收缓冲区中,这就有一问题,上面也说过了,在对端接收缓冲区如果满了的话,那么就会导致发送的报文被丢弃,这已经不是可不可靠性的问题了,因为可以通过超时重传等等的机制来保证,但是这里带来的问题不就是浪费,是一种低效的吗,如果满了的话,还一次性又发来一大推,然后又丢了???这不就很低效,浪费吗???所以发送端是需要知道对端的接收缓冲区的当前接收能力!!!是由对端接收缓冲区中剩余空间的大小所决定的!

其实,我们上面也说了,发送端发送消息,对端原则上是需要给发送端做应答的,不管是捎带还是普通应答,而只要对端给应答,那么不就是双方互相在进行报头/报文的传输吗!双方就需要知道对应对端的接收缓冲区的剩余空间大小!然而TCP协议中有一个关键字段 --- 16位窗口大小!

这个16位窗口大小的内容就是接收缓冲区剩余空间的大小,是自己的!!!不是对端的接收缓冲区的剩余空间的大小!!!(我们所构建的报文一定是给对方的,当然将自己的剩余缓冲区空间大小告诉对方!)

所以尽管可以一次性并行的给对端发送报文,但是也是有上限的,这个上限取决于对端接收缓冲区剩余空间的大小!

我们将这种按照对端接收缓冲区的接受能力来动态调整我们发送速度的机制称为 --- 流量控制! (多发多,少发少,合理控制的机制)(考虑了可靠性,一定程度上防止了丢包,但是流量控制更加考虑的是效率问题)


TCP协议当中还有一个校验和,这个我们不用关心:

TCP协议中的校验和是一个重要的机制,用于确保数据在传输过程中的完整性和准确性。以下是关于TCP校验和的简单介绍:

  • 检测数据完整性:TCP校验和的主要功能是检测数据在传输过程中是否发生了错误。由于网络传输可能会受到干扰(如电磁干扰、硬件故障等),数据可能会被损坏。通过校验和机制,接收端可以验证数据是否与发送端发送的数据一致。

  • 提高可靠性:TCP是一个面向连接的可靠协议,校验和是其可靠性机制的重要组成部分。如果接收端发现校验和不匹配,可以要求发送端重新发送数据,从而确保数据的正确性。


还有一个16位紧急指针,需要了解这个,我们就需要将剩下的标志位谈清楚!

TCP协议报头中有一个保留位(6位),也就是还没想好该怎么用!知道我们想使用再用!除了保留的6位,后面还有6个标志位!

协议的本质就是结构体,tcphdr结构体当中含有条件编译,是对与位段的,这也说明了内核已经可以自己进行大小端的区分了,其中位段是一种数据结构,通常用于将一个字节(8位)或多个字节划分为多个字段,每个字段可以表示不同的信息。位段的设计允许在有限的空间内存储多个标志或状态信息。这是我们C语言所学习的,现在知道了吧!位段主要应用在网络通信中!其实所谓的标志位本质就是报头中的比特位!!!

我们先来说说为什么需要有标志位???

我们先简单谈谈TCP的三次握手,后面会谈到TCP的三次握手的详细过程:

在这个世界上,我们正常通信之前有许多准备工作,有的是没有准备工作的,比如发送邮件,这种直接发送的我们称之为面向数据报,但是如果要打电话进行双方间的通信的话,需要先拨通电话,拨通之后,对方需要将电话接起来,这样的话,电话就建立好通信了。

TCP也是如此,TCP在正常通信之前需要进行三次握手:你可以做我女朋友吗(建立连接的请求)---可以呀,什么时候---就现在!连接关系建立本质就是达成共识!往后就是正常通信了!

这样客户端在某一时刻向接收端发送报文的类型是不一样的!那么可以有多个客户端同时向服务端发送各种各样的报文数据,这样就会导致:接收方收到的TCP报文,一定会存在不同的类型,针对不同的报文类型,接收方要有对应的不同的做法!

双方传输的至少是含有报头的,所以报头当中一定存在标志报文类型的字段!

在TCP协议中,6个标志位(也称为控制位)是TCP头部的重要组成部分,用于控制TCP连接的建立、维护和终止等操作。以下是这6个标志位的详细介绍:

1. SYN(Synchronize Sequence Numbers)

作用用于建立连接。当SYN标志位被设置为1时,表示这是一个连接请求或连接接受报文。

应用场景

  • 在TCP的三次握手过程中,第一次握手(客户端向服务器发送连接请求)和第二次握手(服务器接受连接请求并回复)都会设置SYN标志位。

  • 客户端发送SYN报文时,表示请求建立连接;服务器收到SYN报文后,也会发送一个带有SYN标志位的报文作为响应。

2. ACK(Acknowledgment)

作用:确认号(Acknowledgment Number)字段是否有效。如果ACK标志位被设置为1,则表示确认号字段是有效的,接收方通过确认号来确认已收到的数据。表示该报文是一个应答报文!

应用场景

  • 在TCP通信中,除了第一次握手的SYN报文外,几乎所有的TCP报文都会设置ACK标志位。

  • 例如,服务器在收到客户端的SYN报文后,会发送一个带有ACK标志位的SYN-ACK报文,表示确认收到了客户端的连接请求。

三次握手建立之前,不能正常通信,前两次握手不能发送像"Hello World"的数据,就是三次握手没有完成,也就是只能互发报头了!

那么客户端给服务端发送消息之前不是要进行流量控制吗?那么第一次发送报文的时候不是还不清楚对端的接收缓冲区的剩余空间大小吗???注意!我们第一次发数据是第一次给对端服务器发报文吗???并不是报文!!!而是说双方在通信之前就已经完成三次握手了,三次握手期间已经发送过报头了!!!绝对不会出现数据溢出,丢弃的问题了!!!

3. FIN(Finish)

作用:用于终止连接。当FIN标志位被设置为1时,表示发送方已经完成数据发送,希望关闭连接。

和三次握手类似,客户端给服务端说:我不想玩了,想要断开连接;

服务端:好呀;

服务端:我也要跟你断开连接;

客户端:好呀。

为什么是4次,主要是TCP是全双工的,一方关闭就是只关闭一个通信信道,如果服务端有的还没发完,客户端发完了,那就客户段信道关了,等服务端发完了,也就双发一起实现了完全关闭了!

应用场景

  • 在TCP的四次挥手过程中,发送方(客户端或服务器)在完成数据传输后,会发送一个带有FIN标志位的报文,通知对方自己已经没有数据要发送了。

  • 对方收到FIN报文后,会发送一个ACK报文作为确认,然后自己也会发送一个FIN报文,最终完成连接的关闭。

4. PSH(Push)

作用:表示接收方应尽快将数据推送给上层应用。当PSH标志位被设置为1时,接收方会立即将数据传递给上层应用,而不是等待缓冲区填满后再传递。

应用场景

  • 通常用于实时性要求较高的数据传输,例如在HTTP协议中,当服务器向客户端发送响应数据时,可能会设置PSH标志位,以便客户端尽快处理这些数据。

对端上层应用层很忙,接收缓冲区的所剩空间越来越少,直至为0,那么发送端就只能不发了,但是不发总不能就傻傻的等着吧?!还有如果接收端读走了部分缓冲区的数据,那么发送端又怎么知道?!(我们后面会说到:一旦数据读走了,窗口更新了,这个接收端/服务端,就会主动向客户端发送报文,还有一种方式时客户端会定期像服务端发送一个不携带数据的报文,一发数据就需要ACK,那么客户端也就清楚现在服务端的接收缓冲区的状态了)

PSH就是叫接收方应尽快将数据推送给上层应用!!!是一种催促的机制!!!注意:我们举得例子比较极端,准确来说:当PSH标志位被设置为1时,接收方会立即将数据传递给上层应用,而不是等待缓冲区填满后再传递。

什么是叫对端操作系统赶快读???缓冲区没有数据的时候读取会阻塞,其实有数据的时候也可能会阻塞,就是我们后面会谈到的低水位线和高水位线的问题,举例就是需要满50个字节才会触发read的条件,我们后面提到IO时间就绪的概念的时候详谈!所以PSH的作用就是让对端的read/...条件就绪! 

5. RST(Reset)

作用:用于重置连接。当RST标志位被设置为1时,表示当前连接出现了问题,需要强制断开连接。

应用场景

  • 如果接收方收到一个错误的报文(例如,报文中的序号或确认号不正确),或者接收方没有建立对应的TCP连接,它会发送一个带有RST标志位的报文,通知对方终止连接。

  • 例如,当客户端尝试连接一个不存在的端口时,服务器会发送一个RST报文,拒绝连接。

我们知道TCP建立连接的三次握手的第三次握手是没有应答的,也就是前两次握手尽管丢包了也不怕,因为有应答,能知道,其实客户端在最后一次握手的时候,将第三次握手的ACK发送出去的时候,就已经是客户端三次握手成功了,但是如果在第三次握手的时候丢包了的话,客户端是不知道的,双方只是站在自己的立场,三次握手是看自己有没有发送和收到的(发-收-发;收-发-收)双发三次握手完成是有时间差的:

如果第三次的ACK丢了的话,客户端认为建立成功,但是服务端认为连接失败了,导致连接是否成功的判定不一致, 那么客户端接下来就极有可能向服务器发送数据!!!可是服务器说不是三次握手还没有好吗?于是服务器就会向客户端发送一个RST置为1的报文,表示当前连接出现了问题,需要强制断开连接。

上面这个例子也是比较极端的,其实在通信的过程中,连接出现任何问题,都可以进行重置! 

6. URG(Urgent)

作用:表示报文中有紧急数据。当URG标志位被设置为1时,表示TCP报文中的数据是紧急数据,接收方应优先处理这些数据。

应用场景

  • 紧急数据通常用于控制信息,例如在Telnet协议中,用户可以通过发送紧急数据来中断当前的操作。

  • 当URG标志位被设置时,TCP会使用紧急指针(Urgent Pointer)来指示当前报文的有效载荷中紧急数据的起始位置。

接受缓冲区可以看成是字节流式的接收队列还有因为序号按序到达的机制,那么我们如果有数据想要优先读取并处理的话,直接是行不通的!在计算机网络当中,什么情况是需要被优先处理的呢?

有一种情形:就是上传资料到百度网盘,大小大概是一个G的文件,就会像服务端发送大量的报文,对端缓存区也是收到了该文件的部分的报文,上层会进行备份保存在指定文件当中,但是上传到一半的时候,发现传错了,要取消上传,尽管该文件是一个报文来完成,也是需要死板的到对端接收缓冲区,等待前面的报文处理了,才到该报文,现在就是表示取消上传的报文想要优先被处理,因为前面部分报文是属于同一文件的,上层还需要将前面的报文处理了,但是处理这些报文已经是没有意义的了,所以对端接收缓冲区一旦接收到了含有紧急数据的报文就直接优先处理了,就像我们的取消还有暂停等等!!!

URG是比较不常用的,URG标志位通常是要与TCP报文协议当中的16位紧急指针相配合,如果URG标志位被置为0,表示该16位紧急指针是无效的,为1就是有效了,下面我们来看看16位紧急指针的源码:

__be16 urg_ptr;      // 16位紧急指针

紧急数据并不属于正常数据,他是带外数据!

URG只是代表紧急指针有无效,本质还是需要看16位紧急指针!

紧急指针来指示当前报文的有效载荷中紧急数据的起始位置,本质就是偏移量!紧急数据只有一个字节!也就是因为一个字节,所以他往往可以用来设置状态码!

暂停,取消,继续上传不就可以使用0,1,2来表示嘛!不同的状态码来表示不同的控制命令!

标志位的组合

TCP标志位可以组合使用,以实现不同的功能。例如:

  • SYN-ACK:SYN和ACK标志位同时被设置,表示接受连接请求并确认。

  • FIN-ACK:FIN和ACK标志位同时被设置,表示完成数据传输并确认对方的FIN报文。

TCP的6个标志位是TCP协议的核心控制机制,通过这些标志位,TCP能够实现连接的建立、数据传输、连接终止以及错误处理等功能。这些标志位在TCP的三次握手和四次挥手过程中起着关键作用,确保了TCP协议的可靠性和高效性。

至此,我们TCP包头协议的主要字段我们就谈完了,剩下的字段我们后续会在利用到的时候谈起!

🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔更多精彩请看下文!!!
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2391979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows下安装并使用kubectl查看K8S日志

【1】安装kubectl 官网文档&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后得到 kubectl.exe&#xff0c;放到一个目录下&#xff0c;然后配置环境变量。 此时CMD 进入DOS命令窗口 kubectl version【2】配置config文件 其实就是…

Android studio进阶开发(六)--如何用真机通过okhttp连接服务器

我们学过了如何通过okhttp查询网络上已经发布的网页&#xff0c;但我们还需要在做全栈时保证前后端能够交互。 前要课程 okhttp的使用 真机端口连接 安全认证 由于http的安全性较差&#xff0c;在没有安全协议的情况下&#xff0c;使用自己的后端连接会报错&#xff0c;所以…

WeakAuras Lua Script [ICC BOSS 11 - Sindragosa]

WeakAuras Lua Script [ICC BOSS 11 - Sindragosa] 冰冠堡垒Icecrown Citadel 冰龙 辛达苟萨&#xff08;寒冰信标插件&#xff09; 左 &#xff08;绿&#xff0c;黄&#xff09; 中(蓝&#xff0c;紫&#xff09; 右&#xff08;白&#xff0c;橙&#xff09; lua script&…

电脑开机后出现bootmgr is conmpressed原因及解决方法

最近有网友问我为什么我电脑开机后出现BOOTMGR is compressed&#xff0c;这个提示意思是:意思是启动管理器被压缩了&#xff0c;即使重启也无法正常进入系统。原因有很多&#xff0c;大部分是引导出现问题&#xff0c;或选错了启动硬盘所导致的&#xff0c;下面我们来详细分析…

vite配置一个css插件

vite.config.js的plugins执行函数 该例子只是替换一些css,具体内容不重要,主要看形参的运用 // vite-plugin-css.js export default function cssPlugin() {return {name: vite-plugin-css-post, // 插件的名字&#xff0c;Vite 插件必须有名字enforce: post, // 设定插件执…

React+Taro 微信小程序做一个页面,背景图需贴手机屏幕最上边覆盖展示

话不多说 直接上图 第一步 import { getSystemInfoSync } from tarojs/taro;第二步 render() {const cardBanner getImageUrlByGlobal(member-merge-bg.png);const { safeArea, statusBarHeight } getSystemInfoSync();const NAV_BAR_HEIGHT 44;const navBarHeight NAV…

Spring框架学习day4--Spring集成Mybatis(IOC)

Spring集成Mybatis1.添加jar包&#xff08;pom.xml&#xff09;2.配置sqlSessionFactiory&#xff08;spring.xml)3.再service类中注入Dao代理接口4.测试类5文件结构 Spring集成Mybatis Spring集成Mybatis其核心是将SqlSessionFactory交由Spring管理&#xff0c;并由 Spring管理…

【C++ Qt】容器类(GroupBox、TabWidget)内附思维导图 通俗易懂

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” ✍️绪论​&#xff1a; 本章主要介绍了 Qt 中 QGroupBox 与 QTabWidget 控件。QGroupBox 是带标题的分组框&#xff0c;能容纳其他控件&#xff0c;有标题、对齐方式、是否…

SOC-ESP32S3部分:18-串口

飞书文档https://x509p6c8to.feishu.cn/wiki/NqrMw6X8Si6sSqkyPbxcFRxGnid UART全称是通用异步接收器/发送器&#xff0c;ESP32-S3 芯片有 3 个 UART 控制器。每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。 串口文档参考&#xf…

https下git拉取gitlab仓库源码

git init 创建仓库 参考下面创建公私秘钥对 注意不要以root用户身份创建公私钥&#xff0c;确保保存在/home/username GitLab配置ssh key - 阿豪聊干货 - 博客园 Your identification has been saved in /home/xxx/.ssh/id_ed25519 Your public key has been saved in /ho…

距离计算范围查找距离排序

一 使用场景 目前基于某个位置查附近的人&#xff0c;附近的商家等等&#xff0c;查出来的结果添加距离&#xff0c;或者查附近多大范围内的人或者商家&#xff0c;然后按距离排序已经是IT界一个很通用的功能了。 二 距离计算搜索(百万点集以下) 2.1 球的定义 2.2 两点之…

PS linux 基础篇1-AXI_DMA

系列文章目录 文章目录 系列文章目录前言一、AXI DMA ip核二、BD工程三、PS linux工程1.使用开源的xilinx_axidma-master工程验证驱动2.按照其他的开源进行就行&#xff0c;没什么写的了 前言 PL与PS之间快速的接口&#xff0c;本文为LOOP回环测试 一、AXI DMA ip核 MM2S mem…

AI大模型学习三十、ubuntu安装comfyui,安装插件,修改返回405 bug,值得一看喔

一、说明 ComfyUI是一个开源的、基于节点的Web应用。它允许用户根据一系列文本提示&#xff08;Prompt&#xff09;生成图像。 ComfyUI使用扩散模型作为基础模型&#xff0c;并结合 ControlNet、Lora和LCM低阶自适应等模型&#xff0c;每个工具都由程序中的一个节点表示 二、开…

Collection集合遍历的三种方法

1.foreach循环遍历 格式&#xff1a;for&#xff08;元素的数据类型 变量名&#xff1a;数组或集合&#xff09;{ } 2.使用迭代器遍历 方法名称&#xff1a;Iterator<E> iterator&#xff08;&#xff09; 说明&#xff1a;返回集合中的迭代器对象&#xff0c;该迭代…

Taro on Harmony C-API 版本正式开源

Taro 是由京东发起并维护的开放式跨端跨框架解决方案&#xff0c;支持以 Web 的开发范式来实现小程序、H5、原生 APP 的跨端统一开发&#xff0c;从 18 年开源至今&#xff0c;在 GitHub 已累计获得 36,000 Stars。 Taro x 纯血鸿蒙 在过去的一年中&#xff0c;Taro 经历了显…

知识隔离的视觉-语言-动作模型:训练更快、运行更快、泛化更好

25年5月来自PI的论文“Knowledge Insulating Vision-Language-Action Models: Train Fast, Run Fast, Generalize Better”。 视觉-语言-动作 (VLA) 模型通过将端到端学习与来自网络规模视觉-语言模型 (VLM) 训练的语义知识迁移相结合&#xff0c;为机器人等物理系统训练控制策…

[ARM][架构] 02.AArch32 程序状态

目录 参考资料 1.程序状态 - PSTATE 2.用户模式的 PSTATE 信息 2.1.状态标志 2.2.溢出/饱和标志 2.3.大于等于标志 2.4.指令集状态 2.5.IT 块状态 2.6.端序控制 2.7.指令执行时间控制 3.用户模式访问 PSTATE - APSR 寄存器 4.系统模式的 PSTATE 信息 4.1.状态标志…

React---day4

3、React脚手架 生成的脚手架的目录结构 什么是PWA PWA全称Progressive Web App&#xff0c;即渐进式WEB应用&#xff1b;一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用&#xff1b;随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线…

ArkUI(方舟UI框架)介绍

ArkUI&#xff08;方舟UI框架&#xff09;介绍 构建快速入门 使用ArkWeb构建页面

若依微服务的定制化服务

复制依赖 复制依赖 复制system服务的bootstrap.yml文件&#xff0c;修改port和name 在nacos复制一个新的nacos配置&#xff0c;修改对应的nacos的配置 &#xff0c;可能不需要修改&#xff0c;看情况。 网关修改 注意curd的事项&#xff0c;模块名称的修改