【强烈建议收藏:计算机网络面试专题:TCP协议、UDP协议、TCP三次握手四次挥手、TCP和UDP协议的区别、TCP的拥塞控制?TCP 如何实现流量控制?TCP如何保证传输的可靠性】

一.知识回顾:

之前我们一起学习了HTTP1.0、HTTP1.1、HTTP2.0协议之前的区别、以及URL地址栏中输入网址到页面展示的全过程&&DNS域名解析的过程、HTTP协议基本概念以及通信过程、HTTPS基本概念、SSL加密原理、通信过程、中间人攻击问题、HTTP协议和HTTPS协议区别、HTTP协议、HTTP请求报文和响应报文、HTTP请求报文常用字段、HTTP请求方法、HTTP响应码。接下来我们就来学习一下【强烈建议收藏:计算机网络面试专题:TCP协议、UDP协议、TCP三次握手四次挥手、TCP和UDP协议的区别、TCP的拥塞控制?TCP 如何实现流量控制?TCP如何保证传输的可靠性】,一起学习吧。

在这里插入图片描述

二.控制传输层协议TCP

传输控制协议 TCP一种基于连接的可靠的稳定的无重复的传输协议。

2.1 TCP头部信息

TCP协议头部信息结构图如下:

中文版:
image.png
英文版:
image.png

TCP头部信息各字段含义:

  1. 16位源端口号(Source Port):发送主机中进程的端口号
  2. 16位目的端口号(Destination Port):接收主机中进程的端口号
  3. 32位序列号(Sequence Number):每一个包中都包含序列号,序列号被系统初始化为某个随机值ISN。后续的TCP报文段中序号加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025
  4. 32位确认号(Acknowledgment Number):目的主机返回确认号,使源主机知道某个或几个报文段已被接收
  5. 四位首部长度(Header Length):由于TCP首部包含一个长度可变的选项部分,所以需要这么一个值来指定这个TCP报文段到底有多长
  6. URG标志:表示紧急指针(urgent pointer)是否有效
  7. ACK标志:表示确认号是否有效。我们称携带ACK标识的TCP报文段为确认报文段
  8. PSH标志:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间(如果应用程序不将接收到的数据读走,它们就会一直停留在TCP接收缓冲区中)
  9. RST标志:表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段
  10. SYN标志:表示请求建立一个连接。我们称携带SYN标志的TCP报文段为同步报文段
  11. FIN标志:表示通知对方本端要关闭连接了。我们称携带FIN标志的TCP报文段为结束报文段
  12. 16位窗口大小(window size) :是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度
  13. 16位校验和(TCP check sum): 由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
  14. 16位紧急指针(urgent pointer) :是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。
  15. TCP头部选项(options) :TCP头部的最后一个选项字段(options)是可变长的可选信息。这部分最多包含40字节。

2.2 TCP客户端与服务端建立连接的大致过程

  1. 三次握手建立TCP连接
  2. 客户端与服务端数据传输
  3. 四次挥手释放TCP连接

三.TCP三次握手与四次挥手的详细过程

3.1 三次握手过程

  1. 由客户端的某个进程主动发起TCP连接建立,最初两端的TCP进程都处于关闭状态
  2. TCP服务器被动等待客户进程的TCP请求,所以TCP服务器进入监听状态
  3. TCP客户进程向TCP服务器进程发送TCP建接请求报文段,并且进入同步已发送状态
  4. TCP连接请求报文段首部中的同步位SYN被设置为1,表明这是一个TCP连接请求报文段,32位序列号字段seq被设置了一个初始值x,作为TCP客户进程所选择的初始序号。
  5. TCP服务器进程接收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并且进入同步已接收状态,该报文段首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段。序号字段seq被设置了一个初始值y,作为TCP服务器进进程选择的初始序号,确认号字段ack的值被设置成x+1,表明接收到了TCP客户进程序号为x的报文。
  6. TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并且进入连接已建立状态,报文段首部中的确认位ACK设置为1,表明这是一个普通的TCP确认报文段。序列号字段seq设置为x+1,确认号字段ack的值被设置成y+1,表明接收到了TCP服务进程序号为y的报文,TCP服务器进程收到该确认报文段后也进入连接已建立状态image.png

面试官:假如TCP连接的建立使用两次握手而不是三次握手可以吗?

  1. 假设TCP客户进程发送了一个TCP请求报文段,但是该报文段在网络结点中被长时间滞留了,TCP客户采用超时重传机制重发TCP请求报文段并且被TCP服务进程接收,TCP服务进程发送一个TCP连接请求确认报文段,然后TCP服务进程和客户进程可以进行数据的传输,数据传输完成以后双方都处于关闭状态。
  2. 随后滞留在网络结点中的那个失效的TCP请求报文段被TCP服务进程接收,TCP服务进程又发送一个TCP连接请求确认报文段,并且进入连接已建立状态,由于TCP客户进程并没有发起新的TCP连接请求,并且已经处于关闭状态了,因此不会理会TCP服务器发送的报文段,但是TCP服务器进程已经进入了连接已建立状态,他认为新的TCP连接已经建立好了,就会一直等待TCP客户进程发来数据,将会浪费TCP服务器主机的很多资源。

image.png

3.2 四次挥手过程

TCP通过四次挥手来释放连接,数据通信结束后,TCP双方都可以释放连接。

  1. 假设由客户进程主动关闭TCP连接
  2. 客户进程发送连接释放报文段,并且进入终止等待1状态,该报文段中的首部终止位FIN设置位1,ACK设置为1,表明这是一个连接释放报文段,同时也对之前接收打报文段进行确认,seq=u表示TCP客户进程之前已发送过的数据的最后一个字节的序号+1,ack=v表示客户进程之前已收到的数据的最后一个字节的序号+1
  3. 服务器进程接收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并且进入关闭等待状态,此时TCP客户进程到服务器进程这个方向的连接就释放了,这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了,但是TCP服务器进程如果还有数据需要发送,客户进程则还需要接收,这个状态可能会持续一段时间,直到TCP服务器进程将数据发送完毕。
  4. TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段。
  5. 当TCP服务器进程的没有数据要发送了后,释放连接(被动关闭),TCP服务器进程发送TCP连接释放报文段并进入最后确认状态。FIN=1,ACK=1表明这是一个连接释放报文段,seq=w,ack=u+1同时也对之前收到的报文段进行确认。思考:为什么seq=w,而不是seq=v+1呢?
  6. TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态
  7. TCP服务器进程收到该报文段后就进入关闭状态
  8. 而TCP客户进程还需要经过2MSL后才能进入关闭状态。MSL(Maximum Segment Lifetime)意思是最长报文段寿命,RFC793建议为2分钟在这里插入图片描述

面试官:为什么TCP释放连接是四次挥手呢,不是三次挥手?

  • 假设此时我们的客户端发起要释放连接的过程,将我们的请求发送给服务器,但是此时服务器还有可能继续将数据发送给客户端,所以,不会立即进行中断连接,而是先回给客户端一个报文,报文的内容就是你的释放连接请求我收到了,但是此时我还在传送数据,所以你需要等一等,我的数据传输完成后我就可以进行释放连接的操作了。这也就是比三次释放连接多的一次连接的好处,避免一些数据的丢失情况的发生。

面试官:为什么TCP客户进程还需要经过2MSL后才能进入关闭状态?

  • 假设TCP客户进程收到TCP连接释放报文段,并且针对该报文段发送普通的TCP确认报文段后马上进入关闭状态,但是该确认报文段丢失了,TCP服务器进程无法收到该确认报文段,TCP服务器程序就会以为之前发送的TCP连接释放报文段TCP客户进程没有收到,然后TCP服务器进程会对之前所发送的TCP连接释放报文段超时重传,并仍处于最后确认状态。由于TCP客户进程已经处于关闭状态了,不会处理TCP服务器进程发送的连接释放报文段,这样就会造成TCP服务器反复发送TCP连接释放报文段,并且一直处于最后确认状态而无法进入关闭状态。因此客户端等待2MSL可以确保服务器进程收到最后一个TCP确认报文。image.png

四.TCP可靠传输的实现

  1. 分段传输:应用数据根据MSS(Maxitum Segment Size 最大分段大小,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460 )值被分割成TCP认为最适合发送的数据段。

    注意:在运输层的分段传输(分组传输)和网络层的IP数据报分片传输的区别:分段传输只有TCP协议才有的,并且分段的依据为MSS,分片传输的依据为MTU。

  2. 超时重传:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

  3. CRC校验和:TCP将保持它首部和数据的检验和如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。

  4. 对失序数据包重新排序以及去重:TCP 为了保证不发生丢包,就给每个包一个序列号,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据就可以实现数据包去重。

  5. 流量控制:TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。接收方有即时窗口(滑动窗口),随ACK报文发送。(TCP 利用滑动窗口实现流量控制)

  6. 拥塞控制 : 当网络拥塞时,减少数据的发送。

五.TCP可靠传输之流量控制

5.1 TCP流量控制的基本概念

  1. TCP 利用滑动窗口实现流量控制。
  2. 流量控制是为了控制发送方发送速率,保证接收方来得及接收。
  3. 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。
  4. 将窗口字段设置为 0,则发送方不能发送数据。

5.2 为什么需要流量控制?

  1. 因为双方在通信的时候,发送方的速率与接收方的速率是不一定相等,如果发送方的发送速率太快,会导致接收方处理不过来。如果接收方处理不过来的话,就只能把处理不过来的数据存在接收缓冲区(Receiving Buffers) 里(失序的数据包也会被存放在缓存区里)。如果缓存区满了发送方还在狂发数据的话,接收方只能把收到的数据包丢掉。出现丢包问题的同时又疯狂浪费着珍贵的网络资源。因此,我们需要控制发送方的发送速率,让接收方与发送方处于一种动态平衡才好。
  2. 客户端和服务端双方可以进行双向通信,客户端和服务端既可能是发送端又可能是服务端。因此,两端各有一个发送缓冲区与接收缓冲区,两端都各自维护一个发送窗口和一个接收窗口。接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。
  3. 通信双方的发送窗口和接收窗口的要求相同TCP 发送窗口可以划分成四个部分 :已经发送并且确认的TCP段(已经发送并确认);已经发送但是没有确认的TCP段(已经发送未确认);未发送但是接收方准备接收的TCP段(可以发送);未发送并且接收方也并未准备接受的TCP段(不可发送)。

5.3 流量控制核心—滑动窗口机制

5.3.1 流量控制核心机制

流量控制核心采用了典型的滑动窗口机制,之所以流量控制得以实现,并且效率高,并不仅仅局限于滑动窗口机制,还有很多其它的机制,我们一起来学学看。

  1. 应答机制-累计应答:假如TCP 每发送一个数据报,都要进行一次确认应答,当上一个数据包收到了应答了, 再发送下一个。这样的传输方式有一个缺点:数据包的往返时间越长,通信的效率就越低。为解决这个问题,我们使用累计应答。接收方在接收到多个数据包后再根据接收到的数据包进行应答,也称为累计确认
  2. 窗口:窗口的实现实际上是操作系统开辟的一个缓存空间,接收方根据实际情况在应答数据包中告知自己的接收窗口大小。窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值(以字节为单位)。发送方主机在等到确认应答返回之前,必须在缓冲区(发送窗口)中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
  3. 滑动窗口:如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
5.3.2 滑动窗口控制流量的过程
  • 假设主机A发送数据给主机B,在建立TCP连接时,主机B在确认报文中将自己的接收窗口rwnd告知主机A。(假设接收窗口大小为400)
  • 主机A根据主机B的接收窗口大小创建自己的发送窗口(在内存上开辟一块空间缓存一个接收窗口大小的数据),并且假设每个数据包中载荷数据为100Bytes
  • 主机A分别将第一组数据(为了方便讲解假设seq=1,实际上应该为seq=ISN+1), 第二组数据(seq=101)、第三组数据(seq=201)、第四组数据(seq=301)发送给主机B,中间不需要等待主机B的应答数据报(累计应答)
  • 假设第三组数据(seq=201)在输出过程中被丢失了,尽管主机B接收到了第四组数据,但是因为累计应答时只应答最大连续报文,所以应答数据包中ack=201表示序号201之前的所有数据全部正确接收。假设主机B将接收窗口大小调整为300,在应答报文中rwnd=300
  • 主机A接收到应答数据报后,将自己发送窗口中的序号1~200的数据删除,发送窗口往前(向右)移动并且将大小重新设置为300(开辟接收窗口大小的缓存序号为201-500的数据)
  • 主机B将序号为201,301,401的数据报发送给主机B
  • 假设以上三组数据报没有丢失,主机B在接收到所有数据后发送应答数据报,ack=501,并且将窗口调整为100,rwnd=100A
  • 主机A接收到应答数据报后,将自己发送窗口中的序号201~500的数据删除,发送窗口往前(向右)移动并且将大小重新设置为100(开辟接收窗口大小的缓存序号为501-600的数据)
  • 主机A将序号位600的数据报发送给主机B ,按照以上逻辑知道数据发送完毕。image.png
5.3.3 滑动窗口控制流量的过程-接收窗口为0的处理

接收窗口为0的处理:当发送窗口被调整为0后,发送方就不能再发送数据了,假如接收方的接收窗口调整为大于0了,如果不采取特殊措施发送方是不知道的,因为接收方不会主动告知发送方自己接收窗口的大小。这时就需要持续计数器了,当发送方接收到接收窗口为0的应答报文时马上启动一个持续计时器,当定时达到时主动向接收方发送一个零窗口探测报文,该报文只携带一个字节的数据,然后这种逻辑直到接收方回复的接收窗口大于0。image.png

六.TCP可靠传输之拥塞控制

TCP的四种拥塞控制算法
1.慢开始:刚开始发送数据时,不一下向网络中注入大量数据,而是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。
2.拥塞控制:拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是像慢开始阶段那样加倍增长。因此在拥塞避免阶段就有“加法增大”AI(Additive Increase)的特点。
3.快重传:发送方如果收到连续3个冗余ACK,那么发送方就会执行快重传算法,立即重传这个被确认过3次的报文段之后的报文段,这样可以让发送方在超时事件之前知道报文发生了丢失。
4.快恢复:如果发送方连续接收到3个冗余ACK,发送方知道现在只是丢失了个别的报文段,此时调整门限值 ssthresh为当前拥塞窗口的一半,同时设置拥塞窗口 cwnd为新的门限值(发生报文段丢失时拥塞窗口的一半),而不是从1开始。

整个过程如下所示:
在这里插入图片描述

七.控制传输层协议UDP

7.1 UDP基本概念

  1. UDP 是User Datagram Protocol的简称, 中文名是用户数据包协议。

  2. UDP是一种无连接的不可靠的传输协议(不需要进行三次握手和四次挥手)。

  3. UDP不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的,因此适合实时数据传输,例如:IP电话、网络视频会议等实时应用。

7.2 UDP的头部

UDP头部信息
image.png

7.3 UDP单播、多播、广播

7.3.1 使用UDP运输协议可以进行单播、多播和广播。image.png
7.3.2 单播应用

单播应用:

  1. DNS域名解析,域名系统是因特网上作为域名和IP(Internet Protocol Address)地址相互映射的一个分布式数据库。
  2. 当两个网络应用进程间需要快速传输大文件(音视频文件、图片文件等)时也可以使用UDP单播。

浏览器如何通过域名去查询URL对应的IP(对应服务器地址)呢?

  1. 浏览器缓存:浏览器会按照一定的频率缓存DNS记录。
  2. 操作系统缓存:如果浏览器缓存中找不到需要的DNS记录,那就去操作系统中找。
  3. 路由缓存:路由器也有DNS缓存。
  4. ISP的DNS服务器:ISP是互联网服务提供商(Internet Service Provider)的简称,ISP有专门的DNS服务器应对DNS查询请求
  5. 根服务器:ISP的DNS服务器还找不到的话,它就会向根服务器发出请求,进行递归查询
7.3.3 多播应用

多播应用:网络视频会议、教学,视频监控等。IP多播(也称多址广播或组播)技术,是一种允许一台或多台主机(多播源)发送单一数据包到多台主机(一次的,同时的)的TCP/IP网络技术。IP多播通信必须依赖于IP多播地址,在IPv4中它是一个D类IP地址,范围从224.0.0.0239.255.255.255image.png

7.3.4 广播的应用:ARP数据报广播image.png

注意:在进行UDP编程时,UDP包的大小可以达到64k,但实际上MTU大小只有1k多,如果直接发一个超过MTU大小的包,就会在网络层被分片,这样的问题是,如果只要有一个分片在传输中出错了即校验不正确(这是较容易发生的),整个传输的udp包就被丢弃。注意是整个而不是单个分片。这就是为什么发送UDP包通常也是1k多大小的原因。

八.TCP和UDP的区别

TCPUDP
是否面向连接TCP 提供面向连接的服务无连接
是否是可靠传输TCP 提供可靠的传输服务,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达不可靠传输,不适用流量控制与拥塞控制
是否提供广播或多播服务TCP 只支持点对点通信UDP 支持一对一、一对多、多对一、多对多
传输形式TCP 是面向字节流的UDP 是面向报文的
首部开销TCP 首部开销最小20字节,最大60字节UDP 首部开销小,只需要8字节
是否有状态TCP 传输是有状态的UDP 是无状态服务
传输效率由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率低UDP高
消耗资源系统需要实时的维护该连接,TCP消耗系统资源高UDP低
适用场景适用于要求可靠性传输的应用,比如文件传输适用于实时应用,比如IP电话、视频会议、直播等

九.TCP的长连接和短链接

9.1 TCP的长连接

TCP通信双方在建立好连接后,在较长一段时间内保持连接,直至某一方主动关闭连接。长连接多用于操作频繁,点对点的通讯,例如在物联网开发中某下位机需要定时地频繁向服务发送数据等。

9.2 TCP的短连接

通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接。短连接多用于操作不频繁,点对点的通讯,例如:在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。

9.3 TCP长连接和短连接的对比

image.png

十.HTTP 基于 TCP 还是 UDP?

HTTP 3.0 之前是基于 TCP 协议的,而 HTTP3.0 将弃用 TCP,改用 基于 UDP 的 QUIC 协议 。此变化主要为了解决 HTTP/2 中存在的队头阻塞问题。由于 HTTP/2 在单个 TCP 连接上使用了多路复用,受到 TCP 拥塞控制的影响,少量的丢包就可能导致整个 TCP 连接上的所有流被阻塞。

十一.使用 TCP 的协议有哪些?使用 UDP 的协议有哪些?

11.1 运行于 TCP 协议之上的协议

  1. HTTP 协议 :超文本传输协议(HTTP,HyperText Transfer Protocol)主要是为 Web 浏览器与 Web 服务器之间的通信而设计的。当我们使用浏览器浏览网页的时候,我们网页就是通过 HTTP 请求进行加载的。
  2. HTTPS 协议 :更安全的超文本传输协议(HTTPS,Hypertext Transfer Protocol Secure),身披 SSL 外衣的 HTTP 协议
  3. FTP 协议:文件传输协议 FTP(File Transfer Protocol),提供文件传输服务,基于 TCP 实现可靠的传输。使用 FTP 传输文件的好处是可以屏蔽操作系统和文件存储方式。
  4. SMTP 协议:简单邮件传输协议(SMTP,Simple Mail Transfer Protocol)的缩写,基于 TCP 协议,用来发送电子邮件。
  5. POP3/IMAP 协议: POP3 和 IMAP 两者都是负责邮件接收的协议。
  6. Telnet 协议:远程登陆协议,通过一个终端登陆到其他服务器。被一种称为 SSH 的非常安全的协议所取代。
  7. SSH 协议 : SSH( Secure Shell)是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH 建立在可靠的传输协议 TCP 之上。

11.2 运行于 UDP 协议之上的协议

  1. DHCP 协议:动态主机配置协议,动态配置 IP 地址
  2. DNS : 域名系统(DNS,Domain Name System)将人类可读的域名 (例如,www.baidu.com) 转换为机器可读的 IP 地址 (例如,220.181.38.148)。 我们可以将其理解为专为互联网设计的电话薄。实际上 DNS 同时支持 UDP 和 TCP 协议。

十二.感谢

这篇文章的创作离不开这些资源、网站以及作者的帮助,特别说明,表示感谢。

  1. 特别感谢:马士兵教育
  2. 特别感谢:TCP的拥塞控制(详解):一颗程序媛0915
  3. 特别感谢:TCP拥塞控制:HRADPX
  4. 特别感谢: JavaGuide

十三.总结

啊!!终于完了,好多呀!
在这里插入图片描述

这篇文章的内容比较多,相对来说也比较全,如果看到这里了,那就为你的坚持点个赞吧。
计算机网络真的比较重要,大家一定要重视起来,如果你想要之后走的更高、更稳,那就坚持下去吧。
创作不易,点个赞+关注一下我,为你带来更多优质的内容。
我是硕风和炜,我们下篇文章见。

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值