TCP与UDP

news2025/1/23 9:07:17

概述

传输层时向上层的应用层提供通讯服务的,是属于面向通信部份的最高层,同时也是用户功能的最底层

传输层有两个很重要的特点:复用分用

复用:应用层所有的应用进程都可以通过运输层再传到网络层

分用:运输层从网络层收到发送给各个应用进程的数据后,必须分别交付到指明的各个应用进程。

传输层提供应用进程间的逻辑通信。看上去这中通信时水平方向直接传输数据,但是实际上这两个运输层之间没有水平方向的木李连杰。

与网络层之间的区别:

网络层是为主机之间的通信提供服务,而传输层则是在网络层的基础上,唯一用进程之间的通信提供服务、

运输层向高层用户屏蔽了下面网络和信息姐,它使进程看见的好像再两个运输层实体之间有一条端到端的通信道路,但实际上逻辑通信信道对上层的表现因运输层使用的不同协议有很大的区别。

此外,运输层还应当有试错检测。

两个协议:

TCP协议(传输控制协议):体统面向连接的服务,在传输数据的时候必须先建立连接,数据传输结束后还要释放连接。TCP不提供广播和多播服务。尽管下面的网络是不可靠的,TCP也要尽可能提供一条双工可靠的通信信道。TCP要提供可靠的、面向连接的运输服务,因此不可避免的增加开销,例如确认、流量统计、计数器以及连接管理等

UDP(用户数据报协议)::UDP传输数据时不需要先建立连接,远程主机的运输层收到UDP的报文后,不需要给出任何确认。虽然UDP不提供可靠的交付,但是由于UDP非常简单,在某种情况下是一种最有效的工作方式。例如DNS服务就需要UDP

端口

软件端口是应用层的各种协议进程与传输实体进行交互的地点。

端口号指具有本地意义,他只是为了表基本计算机应用层中的各个进程再和运输层交互时的层间接口,在互联网中不同的计算机相同的端口。是没有实际意义的.15位端口号允许有65535个不同的端口

分类:

  • 服务端使用的端口号
    • 数值端口号:0~1023 比如说HTTP 80 FTP21
    • 等级端口号:104~49151,这类端口号是为没有数值端口号的应用程序使用的,要使用这类端口号,必须再IAIN按照规矩进行登记,防止重复使用
  • 客户端使用的端口号:又称为短暂端口号:再4915~65535

UDP

UDP再IP的数据报服务上加入了很少一点功能:复用、分用、差错检测功能。

特点:

  • UDP是无连接的:发送前是不需要建立连接的,发送数据结束后也没有连接可以释放,因此减少了开销和发送数据之前的时延
  • UDP使用尽最大努力交付。这种交付不保证可靠交付,因此主机不需要维护复杂的链接状态表
  • UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付网络层。UDP对应用层浇下来的报文,既不拆分也不合并,而是保留这些报文的边界。【对于网络层交付上来的数据,去除首部就直接交付到上层的应用层,对于应用层交付下来的数据,加上首部后就直接交付给网络层】
    • 报文太长,,直接交付给网络层后还需要分片,会降低网络层的效率
    • 保温太短,IP数据报的相对长度太长,也会降低效率
  • UDP没有拥塞控制:网络发生拥塞时不会使源主机的发送效率降低。这对某些应用的实时性很重要
    • 但是也可能会造成严重的网络拥塞
  • UDP支持一对多、多对一、多对多、一对一的交互通信
  • UDP首部的开销小,只有8个字节(32位),比TCP20字节的首部要短

首部

用户数据包UDP = 数据字段+首部字段

首部字段仅有8个字节,由4个字段组成,每个字段的长度都是2字节

  • 源端口:源端口号,有需要对方回信时选用,不需要时可以全为0
  • 目的端口:再重点交付报文时必须使用
  • 长度:UDP用户数据报的长度,最小值位8(仅含有首部,没有数据)
  • 检验和:检验UDP用户数据包再传输中是否有错,有错丢弃不接受
    • 在表首加入一个长度位12字节伪首部,分别为目的地址、源地址 0 协议,UDP长度
    • 检验和字段置零,UDP用户数据报凑够偶数字节(如果需要就补一个全为0的字段,在后续也不发送);
    • 计算所有16位的和秒如果超出了就把进位放在末尾
    • 对所有的计算结果进行取反即为检验和。如果结算结果16位全为1,则表示正确,反之则为错误,到时候接收方可以不接受
      • 优点:
        • 简单
      • 缺点
      • 效果差

TCP

TCP时TCP/IP中非常复杂的一个协议

特点:

  1. TCP时面向连接的运输层协议。也就是说,应用层在使用TCP协议之前,必须先建立TCP连接。在结束之后也必须释放掉这个链接。
  2. 每条TCP连接只能有两个端点。每一条TCP连接只能是点对点的、一对一的
  3. TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复,并且按按序到达
  4. TCP提供全双工通信,TCP允许通讯双方的应用进程在任何时候都能发送数据,TCP连接的两端都设有发送缓存和接收缓存。
  5. 面向字节流。TCP中的流指的是流入到进程或者从进程流出的字节序列。整体的含义时:虽然应用程序和TCP的交互是一次一个数据块,但是TCP把应用程序交下来的数据仅仅看成一连串的无结构的字节流。TCP不保证接收方应用程序收到的数据块和发送方的数据块数量一一对应(但是数据量对应),接收方的应用程序必须有能力识别接收到的字节流,把他还原成有意义的应用层数据。

TCP报文段的首部格式

TCP报文段的前20字节是固定的,后面有4n字节是根据需要而增加的。因此TCP首部的最小长度是20字节

源端口和目的端口

各占两个字节,分别写入元端口号和目的端口号,与UDP的分用相似。

序号

占4个字节,

序号范围是0~2^32 -1,序号增加到2^32 -1后,下一个序号又会回到0,也就是说序号使用了mod 2^32运算。

在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,首部中的序号字段值指的是本报文段所发出的数据的第一个字节的序号

这个字段也被称为报文段字段

确认号

占用4个字节

是期望收到对方下一个报文段的第一个数据字节的序号。

若确认号位N,则表明到序号N-1位置所有的数据都已经正确收到了

数据偏移

占4位

他指出TCP报文段的数据起始位置距离TCP报文段的起始位置的距离。实际上就是指出TCP报文段的首部长度

4位二进制表示的最大的十进制数字是15,因此数据偏移量的最大值为60字节,这是TCP首部的最大长度,(选项的长度不能超过40字节)

保留

占6为,保留位今后使用,但目前应为0

6个控制位,用来说明本报问的性质
紧急URG:

当URG=1,表明紧急指针阻断有序。告诉该系统此报文中有紧急数据,应该尽快传送。就不再按照原来的排队顺序传送,而是把它查到本报文段数据的最前面,但是紧急数据也是普通数据,需要配合紧急指针字段使用

确认ACK

当ACK=1时确认号字段有效,当ACK=0时,确认号无效

推送PSH

当两个应用进程进行交互式的通信时,又是在一段的应用程序希望能够快速的收到对方的相应,在这种情况下,会将PSH设置为1,这时候就不会在等待缓存填满再向上交付,而是直接交付。

复位RST

表名出现了严重的差错,必须释放连接,然后重新建立连接

同步SYN

再连接建立时用来同步序号

当SYN = 1而ACK = 0时,表示这是一个连接请求报文段,若同意建立连接,则将响应中的ACK=1、SYN=1.

所以SYN置为1表示这是一个连接请求或者连接接收报文

终止FIN

用来释放一个连接。当FIN=1时,表示此报文段发送的数据已经发送完毕,要求释放运输链接

窗口:

占两个字节

窗口之时0~2^16 -1之间的整数,窗口之的是发送本报文段的一方的接收窗口(不是自己的)。窗口之告诉对方:从本报文段首部中的确认号算起,接受放目前允许对方发送的数据量。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之:窗口值作为接收方让发送方设置其发送窗口的依据

窗口字段明确指出了允许对方发送的数据量。窗口值经常在动态的变化

检验和
紧急指针
选项

内部有MSS(数据字段的最大长度)、选择确认、时间戳

TCP连接

TCP把连接作为最近本的抽象,TCP的许多特性都与TCP面向连接这个基本特征有关。

套接字(socket):IP:端口号

每一条TCP连接唯一的被通信两端的两个断电所确定,即

TCP连接::={socket1,socket2}={(IP1:port1),(IP2:port2)}

可靠传输的工作原理

停止等待协议

停止等待就是没法送完一个分组就停止发送,等待对方的确认,在收到确认后在发送下一个分组

无差错情况

M1发送过去后收到M1的确认回复,就继续发送M2

出现差错

如果M1没有接收到数据或者M1发现验证完数据有误选择丢弃报文后不会进行任何操作,A超过一定时间没有接收到确认就认为之前的分组丢失了,就会重新发送之前的分组。这个过程就叫做超时重传。实现超时重传,就依赖于一个超时计时器。如果超时计时器收到了对方的确认,就撤销已经设置的超时计时器。

需要注意的三点:

  1. 发送放发送完一个分组,必须暂时保存已经发送的副本,只有在收到相应的确认后才可以清除这个分组副本
  2. 分组和确认分组都必须进行编号,这样子才能够确认哪一个发送出的分组收到了确认,而哪一个分组好没有收到确认
  3. 超时计时器设置的重传时间应当比数据分组传输的平均时间更长一点。【需要考虑网络阻塞这种情况】
确认丢失和确认迟到

发送方在设定超时重传的时间内收到确认,并不知道自己发送的分组出现了什么原因,这时候就需要重新传输,接收方收到了重复的分组,就会采取两种措施:

  1. 丢弃这个重复的分组,不向上层重复交付
  2. 向A发送确认

上述这种可靠传输协议常称为自动重传请求ARQ。意思是重传请求时自动进行的。

信道利用率信道利用率比较低

连续ARQ协议

ARQ是TCP的精髓所在,主要采用的是滑动窗口协议,这种协议比较复杂。

其实就是发送方维护一个发送窗口,只要是位于这个窗口内的分组连续发送出去,不需要对方确认,而接受方一般都是采用了积累确认的方式。接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,安排需到达的最后一个分组发送确认。

优点: 容易实现,即使确认丢失也不必重传

缺点:不能像发送方及时反映接收方已经正确收到的所有分组

关于滑动窗口需要住的:
关于缓存:
  1. 缓存空间和需要都是有限的,并且是循环使用的
  2. 发送方不应该发送速度过快,否则接收方没缓存空间进行存放分组
发送方的窗口应该小于等于接收方的窗口
其他:
  1. 发送方的窗口是根据接收方设置的,但是同一时刻发送窗口并不是总是和接收方的窗口一样大。这是因为通过网络传送窗口需要经历一定的事件之后,以及还需要考虑网络阻塞
  2. 对于不按序到达的数据TCP经常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付给上层
    1. 丢弃的话简单实现,但是对网络资源的利用不利
  3. TCP要求接收方必须有积累确认的功能,这样子可以减小传输开销。接收方可以再合适的时候发送确认,也可以再自己有数据要发送时把确认信息顺带发送

TCP流量控制

TCP流量控制就是让发送方的发送频率不要太快,要让接收方来得及接受

发送方的窗口不能超过接收方给出的接收窗口的数值。【TCP的窗口单位是字节,不是报文段】

image-20230307090241554

持续计时器

此外还会存在一个僵局:

当接收方向发送方发送了零窗口的报文之后,过了一段时间有存在了一些缓存,于是接收方向发送方发送了一个rwnd(接收窗口)=400的保温段,但是再传输过程中丢失了,那么接收方就会一直发送,发送方一直等待,为了解决这个僵局采用了持续计时器

TCP为每一个连接都设置了一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就会发送一个零窗口探测报文段(仅携带1字节的数据),而对方再确认这个探测报文段时给出了现在的窗口值。如果窗口仍未0,就重新设置持续计时器。如果不为0,就返回了新的窗口值,打破了僵局

糊涂窗口综合征

TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1字节(这样子会使接收缓存腾出来1字节),然后像发送方发送确认,并把窗口设置为1字节,但是发送放的报文段首部至少40字节,接着发送方发来了一字节的数据(41字节),接收方发送确认,仍将窗口设置为1字节。这样子进行下去,会使网络的效率很低

解决方案:

可以让接收方等待一段时间,使得或者接收缓存已有足够的空间容纳一个最长的报文段,或者等待接收缓存已有一半空闲空间。

此外,发送方也可以不发送太小的报文段,而是把数据积累成足够大的报文段,或者达到接收方缓存的空间的一半大小

也可以配合使用: 发送方不发送很小的报文段的同时,接收方也不要再缓存刚有一小点的空间就急忙把这个很小的窗口大小信息通知给发送方

TCP的拥塞控制

拥塞? 拥塞指的是网络中对某一字段的需求超过了该资源所能提供的可用部分,使得网络的性能变差

拥塞往往是很多因素引起的且常常趋于恶化,拥塞控制与流量控制密不可分。

拥塞控制就是防止过多的数据注入到网络中,这样可以是网络中的路由器或者链路不至于过载。拥塞控制的所做的都有一个前提:网络能够承载现有的网络符合。这是一个全局性的过程,涉及到所有主机、路由器以及与降低网络传输性能的有关的所有因素。

当网络的吞吐量明显小于理想的吞吐量就会进入到轻度阻塞,但是网络的吞吐量持续下降,这时候就会进入一个拥塞状态,当达到0时,网络已经无法工作,这时候就成了所谓的死锁。

拥塞控制非常难设计,因为它是一个动态的问题,而不是静态的。目前存在两种方式:开环控制、闭环控制

开环控制就是在设计网络的时候就把所有的情况都考虑到,力求网络在工作时不产生拥塞,但一旦整个系统运行起来,就无法再进行改正。

闭环控制是基于反馈环路的概念,主要措施:

1. 检测网络系统以便于检测到何时、何处发生
1. 把用色发生的信息传送到可采取行动的地方
1. 调整网络系统的运行已解决出现的问题

控制方法

控制算法:慢开始、拥塞避免、快重传、快恢复,这几种算法也是基于窗口的拥塞控制

慢开始算法

当主机再已建立的TCP连接上开始发送数据时,并不清楚当前网络的负荷状态,。如果立即把大量的数据字节注入到网络中,那么就有可能引起网络阻塞。一般来说先进行探测,即由小到大逐渐增大注入到网络中的数据字节,也就是说,由小到达逐渐增大拥塞窗口的数值

一般来讲设置初始的cwnd(拥塞窗口)的值为1或者2,每次确认成功就乘2(重传确认不进行该操作)。为了防止拥塞窗口增长的过大引起网络阻塞,还需要设置一个慢开始门限(ssthresh)状态变量,可以设置的大一些,比如说发送窗口的最大容许两

基础如下:

cwnd< ssthreash :使用慢增长

cwnd > ssthrash: 使用拥塞避免算法

cwnd == ssthrash: 慢开始和拥塞避免算法都可以使用

拥塞避免算法

目的是为了让拥塞窗口缓慢增长,使拥塞窗口不再是像开始那样加倍增长,而是进行加法进行增大,这个过程就是加法增大。使得拥塞窗口线性缓慢增大

如果cwnd增长到一定值之后网络出现了超时,这是网络发生阻塞的标志,这时候需要调整门限值:ssthresh=cwnd/2,然后cwnd重置,再重新进行之前的流程。

快重传

个别报文可能会丢失,而不是发生了网络拥塞,这可能使发送方认为网络发生了拥塞,错误的开启了慢开始。使得cwnd有设置了1,不必要的降低了传输效率

快重传算法可以让发送方尽早地知道发生了个别报文段丢失。快重传首先要求接收方不要等待自己发送数据时才稍带确认,而是立即发送确认,及时收到了失序的报文段,也要立即发送对已收到的报文段的重复确认。

比如书评M3丢失了,收到了M4、M5、M6、M7,这时候会发送重复确认,都进行确认M2,接收方只要一连收到了3个重复的确认就知道当前没有发生网络阻塞,知识发生了丢失,这时候再次重传少收到的报文段(M3)即可

快恢复

发送方在收到一连串3个重复确认后,知道使丢失了个别的报文段,先不启动慢启动而是进行快恢复:

  • 调整慢开始门限(ssthresh), ssthreash = cwnd /2
  • cwnd = ssthresh + 3 ,加三是因为这三个分组已经离开了网络,已经进行被放在了接收方的缓存中。因此可以适当的把阻塞窗口放大点,另一种说法是cwnd =ssthreash,然后继续接受,收到重复的ACK,cwnd 就自增一,但是如果收到的ACK不是重复的,那就直接将CWND置为ssthresh
  • 重传丢失的数据包,然后继续拥塞避免

TCP的运输连接管理

TCP连接的简历(3握手)

在刚开始的时候,客户端B的TCP服务器进程会先创建一个传输控制快TCB(内部存储一些重要信息,比如说TCP连接表、只想发送和接收缓存的指针、指向重传队列的指针、当前发送和接受的序号等等),然后服务器处于LISTEN(收听)状态,等待客户端的连接请求。

客户端A的TCP进程也先创建传输控制块TCB,然后在建立TCP连接时,向服务器B发送请求报文段,这时候首部的同步位SYN=1,同时选择一个初始序列号seq=x。TCP规定SYN报文段不能携带数据,但是要消耗一个序号,这时候客户进程进入到SYN-SENT(同步已发送状态)

服务端B收到请求报文段后,如果同意连接,则向A发送确认,确认报文中应把SYN和ACK的位置都设置位1,确认学列号ACK= X(客户A生成的初始序列号)+1,同时自己也声称一个初始序号seq = y,这个报文段也不能携带数据,但是要消耗一个序号。这时候TCP服务B进程至于SYN-REVD(同步收到)状态。

TCP客户进程收到B的确认后,同样需要对B给出确认,确认报文段的ACK置为1,确认号位ack = y(TCP服务端的序号)+1;TCP规定ACK报文是可以携带数据的,但是如果不携带数据则不消耗序列号。这种情况下下一个数据的报文段序列号仍是seq=x+1 或者说等于B服务发送来数据报的ack(确认号)。在这时TCP连接已经建立,A进入到了ESTABLISHED(已建立连接)状态。

B在收到A的确认之后也会进入ESTABLISHED(已建立连接)状态

image-20230307110639644

上述的过程就是三次握手

四次握手

所谓的四次握手只不过是再服务端TCP向客户端TCP发送的数据进行了拆分,再之前为把ACK和SYN(等于1的时候不携带数据)都置为1,然后自己在生成一个序号。而四次挥手是把这个过程拆成了两部分:

  • 先发送一个确认报文段(ACK=1 ack=x+1)
  • 然后再发送一个同步报文段(SYN=1,seq = y)

这两中效果时一样的

为什么要进行三次握手,不进行两次或者4次?
进行两次握手

进行两次握手无非是在三次握手的基础上,省略了最后一次握手(进行确认)

最后一次确认主要是为了防止已失效的连接请求报文段忽然传到了服务端,,从而产生错误。

已失效的连接请求报文段: 客户端发送了报文因为网络拥塞没有让服务端B接收到,由于自动重发机制,客户端A就再次进行了重发了一个新的请求。但是旧的请求比新的请求先打到服务端B,就误认为这就是A的一次请求,于是就像A发送了确认报文段,同意建立连接。这时候客户端B以为已经建立了新的运输连接,一直等待A发送数据,这样会导致数据的白白浪费

不进行两次握手

无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;

三次握手在服务端收到建立连接请求后会像客户端发送一个应答,这时候客户端就会对此进行一个检测,如果这个ACK不是最新的ACK,就会发送RST数据报文段,结束这段连接。

不进行四次握手

三次即可完成,进行四次握手,不过是资源的浪费

TCP连接释放

【1】数据传输结束后,通信的双方都可以释放连接,现在A和B都处于ESTABLISHED状态(已建立连接状态)。A(客户端)的应用进程先向其TCP发出连接释放报文段,并停止在发送数据。主动关闭TCP连接。A把连接释放的报文段首部的终止控制位FIN置为1,其序号seq=u,它等于前面已传送过的的数据的最后一个字节的序号加一。这时候A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。TCP规定,FIN报文段即使不带数据也需要消耗一个序号

【2】B收到连接释放报文段后即发出确认,确认号是ack+1,而这个报文段自己的序号是v,等于B前面已传送过去的数据的最后一个字节的序号加一。然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接已经释放了,这时候TCP连接处于版关闭状态,即A已经没有数据要发送了,但是B若发送数据,那么A仍要接受,也就是说B到A这个方向的连接未关闭,这个状态会持续一段时间。

【3】A收到了来自B的确认后就会进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。

若B已经没有要想A发送的数据,其应用进程就通知TCP释放连接,这是B发出的连接释放报文段必须使FIN=1,假定B的序号为w(版关闭状态B可能有发送了一些数据),B还必须重复上次已经发送过的确认号ack=u+1,这是B进入LAST-ACK(最后确认状态),等待A的确认

【4】A收到B的连接释放报文段后,必须对此发出确认。在确认文段中ACK置为1,确认号ack=w+1,而自己的序号是seq=u+1,然后进入到TIME-WAIT(时间等待)状态。现在TCP连接还没有释放掉,必须等待时间等待计时器设置的时间2MSL(最长报文段寿命)后,A才会进入到CLOSED状态。

为什么要设置2MSL

首先,是为了保证A发送的最后一个ACK报文段能够到达B,这个ACK报文段有可能丢失,因为LAST-ACK状态的B收不到对以发送的FIN+ACK报文段的确认,B会超时重传这个FIN+ACK报文段。而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后A和B都正常进入到CLOSED状态。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段就直接释放连接。无法接收到B的FIN+ACK报文段,因为也不会再发送一次确认报文段。导致B无法正常进入到CLOSED

其次是为了防止已失效的链接请求报文段出现在本连接中。A在发送完最后一个ACK报文段后,在经过2MSL,就可以是本连接持续时间内的所有报文段都从网络上消失

TCP还设置了一个保活计时器

如果客户端的主机忽然出现故障,服务端无法收到客户端发送来的请求。服务器没收到一次客户端发送来的数据,就hi重新设置以下保活计时器,时间的设置通常是2小时。若长时间没有收到数据,服务器就会发送一个探测报文段,以后每个75s发送一次,若一连发送了10个探测报文段然然没有客户相应,服务器就认为这个客户端出现了故障,然后就关闭这个连接

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

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

相关文章

【Unity】多分辨率适配

笔者按&#xff1a;使用Unity版本为2021.3LTS&#xff0c;与其他版本或有异同。请仅做参考 一、前言。 本文是笔者在学习使用Unity引擎的过程中&#xff0c;产学研的一个笔记。由笔者根据官方文档Unity User Manual 2021.3 (LTS)/Create user interfaces (UI)/Unity UI/UI 操作…

mingw编译opencv

我这里是msys2 这个是msys2的教程 https://blog.csdn.net/qq_39942341/article/details/105931335?ops_request_misc%257B%2522request%255Fid%2522%253A%2522167821146216800197067008%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&requ…

【LeetCode】剑指 Offer 24. 反转链表 p142 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/fan-zhuan-lian-biao-lcof/submissions/ 1. 题目介绍&#xff08;24. 反转链表&#xff09; 定义一个函数&#xff0c;输入一个链表的头节点&#xff0c;反转该链表并输出反转后链表的头节点。 【测试用例】&#xff1a; 示…

C++右值引用/移动语义

在此之前&#xff0c;我们所用的引用&#xff0c;其实都是左值引用。 int a 10; int& ra a; 下面我们来重新认识一下引用&#xff1a; 而何为左值&#xff1f;左值引用其实是什么&#xff1f;请往下看~ 左值是一个表示数据的表达式(如变量名或解引用的指针)&#xff…

77. writerows写入多行

文章目录1. 目标任务2. 准备工作3. writerow单行写入4. writerows多行写入5. a以追加的模式写入值6. 总结1. 目标任务 新建【各班级成绩】文件夹&#xff1b; 在该文件夹下新建一个【1班成绩单.csv】文件&#xff1b; 在该文件中写入下面的内容&#xff1a; 成绩 姓名 刘一…

CentOS 8搭建EMQX集群

概览 EMQX (opens new window)是一款大规模可弹性伸缩的云原生分布式物联网 MQTT (opens new window)消息服务器。 EMQ X 设计目标是实现高可靠&#xff0c;并支持承载海量物联网终端的MQTT连接&#xff0c;支持在海量物联网设备间低延时消息路由: 1. 稳定承载大规模的 MQTT 客…

Allegro如何添加菜单栏操作指导

Allegro如何添加菜单栏操作指导 用Allegro设计PCB的时候,将常用的命令放在菜单栏的话可以方便使用,省去设计时间,菜单如下图 Allegro支持自由添加或者删除菜单,具体操作如下 点击View点击Customize Toolbar

【使用vue init和vue create的区别以及搭建vue项目的教程】

vue init 是vue-cli2.x的初始化方式&#xff0c;可以使用github上面的一些模板来初始化项目 webpack是官方推荐的标准模板名 使用方式&#xff1a;vue init webpack 项目名称 例如使用github上面electron-vue的模板使用方式&#xff1a;vue init electron-vue 项目名称教程目…

Java的数据库编程:JDBC

Content &#x1f389;1什么是API &#x1f389;2.什么是JDBC &#x1f389;3.数据库驱动包的安装 &#x1f389;4.数据库安装包在idea的使用 &#x1f389;5.JDBC的增删改查的简单实现 今天为大家带来JAVA的数据库编程,也就是用Java实现数据库 数据库的最基本的操作就是…

分布式锁简介

Redis因为单进程、性能高常被用于分布式锁&#xff1b;锁在程序中作用是同步工具&#xff0c;保证共享资源在同一时刻只能被一个线程访问。 Java中经常用的锁synchronized、Lock&#xff0c;但是Java的锁智能保证单机的时候有效&#xff0c;分布式集群环境就无能为力了&#xf…

软件设计师错题集

软件设计师错题集一、计算机组成与体系结构1.1 浮点数1.2 Flynn分类法1.3 指令流水线1.4 层次化存储体系1.4.1 程序的局限性1.5 Cache1.6 输入输出技术1.7 总线系统1.8 CRC循环冗余校验码二、数据结构与算法基础2.1 队列与栈2.2 树与二叉树的特殊性2.3 最优二叉树&#xff08;哈…

VisualSP Enterprise - February crack

VisualSP Enterprise - February crack VisualSP(可视化支持平台)提供了一个上下文中完全可定制的培训平台&#xff0c;它可以作为企业web应用程序的覆盖层提供。无论员工正在使用什么应用程序&#xff0c;他们都能够快速访问页面培训和指导&#xff0c;说明如何最有效地使用该…

C++基础了解-14-C++ 字符串

C 字符串 一、C 风格字符串 C 风格的字符串起源于 C 语言&#xff0c;并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此&#xff0c;一个以 null 结尾的字符串&#xff0c;包含了组成字符串的字符。 下面的声明和初始化创建了一个 RUNOOB …

教你如何搭建店铺—收支管理系统,demo可分享

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建店铺-收支管理。1.2、应用场景以店铺收支管理为核心&#xff0c;维度数据分析&#xff0c;智能指导门店经营&#xff0c;账目清晰一目了然&#xff0c;店铺经营更高效。2、设置方法2.1、表单搭建1&#xff09;新建表单【客户…

如何使用码匠连接 DynamoDB

目录 在码匠中集成 DynamoDB 在码匠中使用 DynamoDB 关于码匠 DynamoDB 是亚马逊 AWS 的一种高性能、全托管的 NoSQL 数据库服务。作为一种数据源&#xff0c;DynamoDB 能够提供高度可扩展性、低延迟和可靠性。它支持多种数据类型和数据模型&#xff0c;包括键-值、文档和图…

元宇宙时代来临,Facebook豪掷百亿是谋略还是赌博?

"Facebook向元宇宙发起冲击&#xff0c;豪掷百亿是谋略还是赌博&#xff1f;"2022年&#xff0c;Facebook宣布将投资100亿美元用于元宇宙技术的开发和推广。这笔巨额资金的投入是否会给Facebook带来巨大的回报&#xff0c;还是一场高风险的赌博呢&#xff1f;首先&am…

【13种css选择器】学css选择器,这一篇就够了

举例形象让你学会&#xff0c;不搞官方话css所有的选择器相邻兄弟选择器后续兄弟选择器后代选择器子代选择器并集选择器(多重选择器)属性选择器伪类选择器伪元素选择器class选择器&#xff08;类选择器&#xff09;id选择器*选择器&#xff08;通配符选择器&#xff09;标签选择…

【算法之旅】初识数据结构与算法

一名软件工程专业学生的算法之旅&#xff0c;记录自己从零开始学习数据结构与算法&#xff0c;从小白的视角学习数据结构&#xff1a;数组、对象/结构、字符串、队列、栈、树、图、堆、平衡树/线段树等&#xff0c;学习算法&#xff1a;枚举、排序、搜索、计数、分治策略、动态…

Windows中配置docker没有hyper-v功能解决方案

&#x1f468; 作者简介&#xff1a;大家好&#xff0c;我是Taro&#xff0c;前端领域创作者 ✒️ 个人主页&#xff1a;唐璜Taro &#x1f680; 支持我&#xff1a;点赞&#x1f44d;&#x1f4dd; 评论 ⭐️收藏 文章目录前言解决步骤&#xff1a;1.新建文档2. 另存为3. 功能…

Tomcat独立部署-Nginx-1.12.2配置SSL

目录 &#x1f3c6;1. 实现思路 &#x1f3c6;2. 重启服务器 &#x1f3c6;3. proxy_pass 后地址带/和不带/的url地址显示 &#x1f3c6;4. 配置SSL证书 &#x1f3c6;5. 遇到问题 &#x1f3c6;6. 参考文章 学习完本篇博客您将掌握&#xff1a; 1、使用Tomcat配置SSL域名…