【计算机网络-传输层】TCP 协议

news2024/9/19 10:45:48

文章目录

  • 1 传输层概述
    • 1.1 传输层的功能
    • 1.2 端口号
  • 2 TCP 报文段
    • 2.1 TCP 报文段首部格式
    • 2.2 TCP 数据传送的过程
  • 3 TCP 连接管理
    • 3.1 TCP 连接的建立——三次握手
      • 3.1.1 客户机向服务器发送 TCP 连接请求报文段
      • 3.1.2 服务器向客户机发送 TCP 连接请求确认报文段
      • 3.1.3 客户机向服务器发送 TCP 确认报文段
    • 3.2 TCP 连接的释放——四次挥手
      • 3.2.1 客户机向服务器发送 TCP 连接释放报文段
      • 3.2.2 服务器向客户机发送 TCP 确认报文段
      • 3.2.3 服务器向客户机发送 TCP 连接释放报文段
      • 3.2.4 客户机向服务器发送 TCP 确认报文段
  • 4 TCP 流量控制和可靠传输
    • 4.1 接收方对发送方的第 1 次流量控制
    • 4.2 接收方对发送方的第 2 次流量控制
    • 4.3 接收方对发送方的第 3 次流量控制
  • 5 TCP 拥塞控制
    • 5.1 慢开始和拥塞避免
    • 5.2 快重传和快恢复

1 传输层概述

1.1 传输层的功能

  • 端到端通信:提供应用进程间的端到端通信(逻辑通信)。因此传输层又称为端到端协议。
  • 差错检测:对首部和数据部分进行检测。
  • 两种协议:面向连接的 TCP、无连接的 UDP。
  • 复用和分用

在这里插入图片描述

概念解释
传输层 TCP 复用发送方的部分应用进程的报文在传输层使用 TCP 协议进行封装
传输层 UDP 复用发送方的部分应用进程的报文在传输层使用 UDP 协议进行封装
网际层 IP 复用发送方不同协议的数据都可以封装成 IP 数据报(IP 协议字段,TCP 为 6,UDP 为 17)
网际层 IP 分用接收方的网际层在去除首部后把数据交付给上层相应的协议(TCP 或 UDP)
传输层 TCP 分用接收方的传输层使用 TCP 协议去除首部后把数据交付给目的应用进程
传输层 UDP 分用接收方的传输层使用 UDP 协议去除首部后把数据交付给目的应用进程

1.2 端口号

  • 端口:应用进程通过端口号进行标识。端口号长度为 16b,能表示 65535 个不同的端口号。
端口号类型解释
0 ~ 1023熟知端口号由 IANA 分配给 TCP/IP 体系结构应用层中最重要的一些应用协议
1024 ~ 49151登记端口号为没有熟知端口号的应用程序使用。要使用这类端口号,必须在 IANA 进行登记,以防止重复
49152 ~ 65535短暂端口号仅在客户端使用,由客户进程在运行时动态选择,通信结束后会被系统收回,以便给其他客户进程使用
  • 需记忆的熟知端口号:
FTPSMTPDNSDHCPHTTPBGPHTTPSRIP
21/20255367/6880179443520

【注】OSPF 不使用传输层协议,所以没有对应的端口号。但 OSPF 的 IP 协议字段值为 89。

2 TCP 报文段

2.1 TCP 报文段首部格式

在这里插入图片描述

  • 源端口和目的端口:各占 2b,端口是传输层与应用层的服务接口。
  • 序号(seq):占 32b,取值范围 0 ~ 232-1。用来指出本 TCP 报文段的第一个字节的序号。
  • 确认号(ack):占 32b,取值范围 0 ~ 232-1。用来指出期望收到对方下一个 TCP 报文段的第一个字节的序号,同时也是对之前收到的所有数据的确认。若确认号为 N,则表明序号 N-1 为止的所有数据都已收到。
  • 数据偏移(首部长度):占 4b,表示 TCP 首部长度。该字段的取值以 4B 为单位,最大字段值为 15,因此 TCP 首部最大长度为 60B。
  • 保留:占 6b,保留为今后使用,但目前应置位 0。
  • 紧急位(URG):当 URG=1 时,此报文段有紧急数据,应尽快传送。
  • 确认位(ACK):当 ACK=1 时,确认号字段才有效。TCP 连接建立后,ACK 必须为 1。
  • 推送位(PSH):当 PSH=1 时,就尽快地交付给应用进程,而不再等到接收到足够多的数据才向上交付。
  • 复位位(RST):当 RST=1 时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接。
  • 同步位(SYN):当 SYN=1 且 ACK=0 时,表明这是一个 TCP 连接请求报文段。对方若同意建立连接,则应在响应的 TCP 报文段的首部中使 SYN=1 且 ACK=1。
  • 终止位(FIN):当 FIN=1 时,表明此 TCP 报文段的发送方已经将全部数据发送完毕,现在要求释放 TCP 连接。
  • 窗口:占 16b,指出发送本报文段的一方的接收窗口的大小,即接收缓存的可用空间大小,用来表征接收方的接收能力。该字段的取值以 1B 为单位。
  • 校验和:占 16b,用来检查整个 TCP 报文段在传输过程中是否出现了误码。
  • 紧急指针:占 16b,用来指明紧急数据的长度。该字段的取值以 1B 为单位。
  • 选项:长度可变,有多种选项。其中有个选项为最大报文段长度(Maximum Segment Size,MSS),表示报文段中数据部分的最大长度。
  • 填充:为了使整个首部长度是 4B 的整数倍。

【注】重点关注 seq、ack、ACK、SYN、FIN 这几个位。

2.2 TCP 数据传送的过程

假设有客户机 A 和服务器 B 已经建立了 TCP 连接。

(1)现 A 向 B 发送 TCP 确认报文段

首部数据部分
seq=201, ack=800, ACK=1100B(seq=201~300)
  • seq=201:指 A 的数据部分是从序号 201 开始的,数据部分总长 100B,因此数据部分的最后一个序号是 300。
  • ack=800:指 A 期望 B 发来的下一个报文段的数据部分序号是从 800 开始的。
  • ACK=1:连接建立后所有传送的报文段都必须置 1。

(2)然后 B 向 A 发送 TCP 确认报文段

首部数据部分
seq=800, ack=301, ACK=1200B(seq=800~999)
  • seq=800:指 B 的数据部分是从序号 800 开始的,数据部分总长 200B,因此数据部分的最后一个序号是 999。
  • ack=301:指 B 期望 A 发来的下一个报文段的数据部分序号是从 301 开始的,同时确认 A 的报文段(seq=201~300)已收到。
  • ACK=1:连接建立后所有传送的报文段都必须置 1。

(3)若 A 向 B 发送 3 个 TCP 确认报文段,其中第 2 个报文段丢失:

首部数据部分
seq=201, ack=x, ACK=1100B(seq=201~300)
seq=301, ack=x, ACK=1100B(seq=301~400)(丢失
seq=401, ack=x, ACK=1100B(seq=401~500)

则 B 仅正确接收第 1 个和第 3 个报文段。此时 B 向 A 发送的 TCP 报文段,应对已正确接收且按序到达的最后一个 TCP 报文段确认,这就是累积确认(更详细的解释见第 4 节内容):

首部数据部分
seq=x, ack=301, ACK=1200B(seq=x~x+199)

3 TCP 连接管理

TCP 连接有三个阶段:连接建立、数据传送(上面已述)、连接释放。

3.1 TCP 连接的建立——三次握手

假设有客户机 A 和服务器 B 准备建立 TCP 连接。

在这里插入图片描述

服务器 B 进程处于 LISTEN(监听)状态,等待客户机 A 的连接请求。

3.1.1 客户机向服务器发送 TCP 连接请求报文段

客户机 A 向服务器 B 发送 TCP 连接请求报文段

首部数据部分
seq=x, ack=0, SYN=1, ACK=0SYN 报文段不能携带数据
  • seq=x:随机选取一个初始序号 x,作为客户机 A 的 TCP 报文段数据部分的初始序号。
  • ack=0:由于 ACK=0,所以 ack 字段无效。
  • SYN=1TCP 连接请求报文段中的同步标志位 SYN 的值必须设置为 1。
  • ACK=0:当 SYN=1,ACK=0 时,表明这是一个 TCP 连接请求报文段

此时,客户机 A 进入 SYN-SENT(同步已发送)状态

【注】TCP 规定同步标志位 SYN 被设置为 1 的报文段(例如 TCP 连接请求报文段和 TCP 连接请求确认报文段)不能携带数据,但要消耗掉一个序号

3.1.2 服务器向客户机发送 TCP 连接请求确认报文段

服务器 B 收到 TCP 连接请求报文段后,向客户机 A 发送 TCP 连接请求确认报文段

首部数据部分
seq=y, ack=x+1, SYN=1, ACK=1SYN 报文段不能携带数据
  • seq=y:随机选取一个初始序号 y,作为服务器 B 的 TCP 报文段数据部分的初始序号。
  • ack=x+1:服务器 B 期望收到客户机 A 发来的下一个报文段的数据部分序号是从 x+1 开始的,同时确认客户机 A 的报文段(seq=x)已收到。
  • SYN=1TCP 连接请求确认报文段中的同步标志位 SYN 的值必须设置为 1。
  • ACK=1:当 SYN=1,ACK=1 时,表明这是一个 TCP 连接请求确认报文段

此时,服务器 B 进入 SYN-RCVD(同步已接收)状态

3.1.3 客户机向服务器发送 TCP 确认报文段

客户机 A 收到 TCP 连接请求确认报文段后,向服务器 B 发送 TCP 确认报文段

首部数据部分
seq=x+1, ack=y+1, SYN=0, ACK=1TCP 确认报文段可以携带数据
  • seq=x+1:客户机 A 的 TCP 报文段数据部分的序号为 x+1。
  • ack=y+1:客户机 A 期望收到服务器 B 发来的下一个报文段的数据部分序号是从 y+1 开始的,同时确认服务器 B 的报文段(seq=y)已收到。
  • SYN=0TCP 确认报文段中的同步标志位 SYN 的值必须设置为 0。
  • ACK=1:当 SYN=0,ACK=1 时,表明这是一个普通的 TCP 确认报文段

此时,客户机 A 进入 ESTABLISHED(连接已建立)状态

【注】TCP 规定普通的 TCP 确认报文段可以携带数据,但如果不携带数据,则不消耗序号。如果该报文段不携带数据,则客户机 A 要发送的下一个数据报文段的序号仍为 x+1。

服务器 B 收到 TCP 确认报文段后,也进入 ESTABLISHED(连接已建立)状态。至此 TCP 连接已建立。

【总结】TCP 建立连接的过程:

客户机:“我有话要跟你讲,不知可不可以?”
服务器:“可以,你讲吧!”
客户机:“好的!blablabla”

3.2 TCP 连接的释放——四次挥手

假设有客户机 A 和服务器 B 准备释放 TCP 连接。

在这里插入图片描述

客户机 A 进程和服务器 B 进程处于 ESTABLISHED(连接已建立)状态

3.2.1 客户机向服务器发送 TCP 连接释放报文段

客户机 A 向服务器 B 发送 TCP 连接释放报文段

首部数据部分
seq=u, ack=v, FIN=1, ACK=1FIN 报文段可携带也可不携带数据
  • seq=u:客户机 A 的 TCP 报文段数据部分的序号为 u,它等于客户机 A 之前已传送数据部分的最后一个字节的序号加 1。
  • ack=v:ack 字段的值为 v,它等于客户机 A 之前已收到数据的最后一个字节的序号加 1。
  • FIN=1TCP 连接释放报文段中的同步标志位 SYN 的值必须设置为 1。
  • ACK=1:当 FIN=1,ACK=1 时,表明这是一个 TCP 连接释放报文段

【注】TCP 规定,终止标志位 FIN 等于 1 的 TCP 报文段即使不携带数据,也要消耗掉一个序号。

此时,客户机 A 进入 FIN-WAIT-1(终止等待 1)状态

3.2.2 服务器向客户机发送 TCP 确认报文段

服务器 B 收到 TCP 连接释放报文段后,向客户机 A 发送 TCP 确认报文段

首部数据部分
seq=v, ack=u+1, FIN=0, ACK=1TCP 确认报文段可以携带数据
  • seq=v:服务器 B 的 TCP 报文段数据部分的序号为 v。
  • ack=u+1:服务器 B 期望收到客户机 A 发来的下一个报文段的数据部分序号是从 u+1 开始的,同时确认客户机 A 的连接释放报文段(seq=u)已收到。
  • FIN=0TCP 确认报文段中的同步标志位 SYN 的值必须设置为 0。
  • ACK=1:当 FIN=0,ACK=1 时,表明这是一个普通的 TCP 确认报文段

此时,服务器 B 进入 CLOSE-WAIT(关闭等待)状态。客户机 A 已经没有数据要发送了。但服务器 B 如果还有数据要发送,客户机 A 仍要接收,即从服务器 B 到客户机 A 这个方向的连接并未关闭,这称为半关闭状态,该状态可能会持续一段时间。

3.2.3 服务器向客户机发送 TCP 连接释放报文段

服务器 B 向客户机 A 发送若干个 TCP 确认报文段,直到发送最后一次报文段,即 TCP 连接释放报文段

首部数据部分
seq=w, ack=u+1, FIN=1, ACK=1FIN 报文段可携带也可不携带数据
  • seq=w:经过发送若干个 TCP 确认报文段,服务器 B 的 TCP 报文段数据部分的序号变为 w。
  • ack=u+1:服务器 B 期望收到客户机 A 发来的下一个报文段的数据部分序号是从 u+1 开始的,同时重复确认客户机 A 的连接释放报文段(seq=u)已收到。
  • FIN=1TCP 连接释放报文段中的同步标志位 SYN 的值必须设置为 1。
  • ACK=1:当 FIN=1,ACK=1 时,表明这是一个 TCP 连接释放报文段

此时,服务器 B 进入 LAST-ACK(最后确认)状态

3.2.4 客户机向服务器发送 TCP 确认报文段

客户机 A 收到 TCP 连接释放报文段后,向服务器 B 发送 TCP 确认报文段

首部数据部分
seq=u+1, ack=w+1, FIN=0, ACK=1TCP 确认报文段可以携带数据
  • seq=u+1:客户机 A 的 TCP 报文段数据部分的序号为 u+1。
  • ack=w+1:客户机 A 期望收到服务器 B 发来的下一个报文段的数据部分序号是从 w+1 开始的,同时确认服务器 B 的连接释放报文段(seq=w)已收到。
  • FIN=0TCP 确认报文段中的同步标志位 SYN 的值必须设置为 0。
  • ACK=1:当 FIN=0,ACK=1 时,表明这是一个普通的 TCP 确认报文段

此时,客户机 A 进入 TIME-WAIT(时间等待)状态,服务器 B 收到 TCP 确认报文段后进入CLOSED(连接关闭)状态。但是 TCP 连接仍未释放,必须经过 2MSL(最长报文段寿命,Maximum Segment Lifetime)的时间后,客户机 A 才能进入 CLOSED(连接关闭)状态

【总结】TCP 释放连接的过程:

客户机:“我准备走了。”
服务器:“等一下,我还有一些话没说完。blablabla”
服务器:“blablabla”
服务器:“blablabla,我说完了,你可以走了。”
客户机:“好的!那我走了!”

4 TCP 流量控制和可靠传输

TCP 协议提供一种基于滑动窗口协议的流量控制机制。TCP 使用了校验、序号、确认和重传等机制来达到可靠传输的目的,在下面的过程中将体现这一特点。

假设有发送方 A 和接收方 B 已建立 TCP 连接,不考虑 TCP 的拥塞控制。再假定 A 只给 B 发送数据,B 对 A 进行流量控制。

在 A 和 B 建立 TCP 连接后,B 告诉 A:“我的接收窗口 rwnd=500”,因此 A 将自己的发送窗口 swnd 也设置为 500。窗口大小是以最大报文段 MSS 为单位的,一般将 MSS 设置为 1B,所以 “swnd=500”意思是发送窗口的大小为 500B。

A 的发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

A 发送数据:seq=1,seq=101,seq=201,seq=301,发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

4.1 接收方对发送方的第 1 次流量控制

但是很不巧,seq=201 丢失了,B 只收到 seq=1,seq=101,seq=301。其中 seq=301 是失序报文段,但 B 不会丢弃它。TCP 作如下规定:每接收到一个失序报文段,就要发送一次冗余 ACK,指明下一个期待的报文数据序号。

很明显,现在 B 期望收到 seq=201 的报文,因此 seq=301 是不会被确认的,这被称为累积确认。现在 B 的接收窗口已经接受了 200B 的数据,还有 300B 未接收,于是发送 ACK=1,ack=201,rwnd=300 的冗余报文给 A。

此时发送方 A 的 swnd 调整为 300,swnd 滑动到首个未确认的数据位置。发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

发送方 A 继续发送 seq=401,对于接收方 B 来说,seq=401 依然是失序报文段,继续发送 ACK=1,ack=201,rwnd=300 的冗余报文给 A。此时发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

4.2 接收方对发送方的第 2 次流量控制

发送方 A 也没有对 seq=201 坐视不理,实质上从发出 seq=201 开始,重传计时器也开始计数了,A 发现计时器超时但仍未收到来自 B 的确认,于是进行超时重传

【注】其实,当发送方 A 连续收到三个冗余 ACK 后,就可以立即重新发送 seq=201,而不必等待计时器超时,这被称为快重传算法,在下一节“拥塞控制”将提到。

接收方 B 收到 seq=201 后,由于网络流量原因,接收窗口需减小到 100B,于是返回 ACK=1,ack=501,rwnd=100 的报文。此时发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

发送方 A 发送 seq=501,此时发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

4.3 接收方对发送方的第 3 次流量控制

接收方 B 收到 seq=501 后,返回 ACK=1,ack=601,rwnd=0 的报文,表示 B 不再接收任何数据。此时发送缓冲区情况如下:

数据1~100B101~200B201~300B301~400B401~500B501~600B601~700B701~800B
swnd
A 已发送
B 已确认
B 已收到

由于发送方 A 的 swnd=0,因此 A 不能发送任何数据了。接收方 B 必须发送一个非零窗口通知,以告知发送方 A:“你可以开始发送大小为 xxx 的窗口了。”所以,A 一直在等待这个通知,只要收到通知,将恢复传输过程。

然而可能会出现这样一种情况:B 发出的通知丢失,A 只能无限等待下去。为了打破由于非零窗口通知报文段丢失而引起的双方互相等待的死锁局面,TCP 为每一个连接都设有一个持续计时器

  • 只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器。
  • 当持续计时器超时时,就发送一个零窗口探测报文段,仅携带 1 字节的数据。
  • 对方在确认这个零窗口探测报文段时,给出自己现在的接收窗口值 rwnd。
    • 如果接收窗口值 rwnd 仍然是 0,那么收到这个报文段的一方就重新启动持续计时器,继续以上过程。
    • 如果接收窗口值 rwnd 不是 0,那么死锁的局面就可以被打破了。

【注】TCP 规定:即使接收窗口值为 0,也必须接受零窗口探测报文段、确认报文段以及携带有紧急数据的报文段。

5 TCP 拥塞控制

5.1 慢开始和拥塞避免

设置一个慢开始门限阈值 ssthresh,初始值为 16。根据发送方的拥塞窗口 cwnd 的大小执行不同的算法:

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

慢开始算法:从 cwnd=1 开始,每经过一个传输轮次(即往返时延 RTT)指数规律增长,cwnd=2,cwnd=4,cwnd=8,当 cwnd = ssthresh = 16 时,改用拥塞避免算法。

拥塞避免算法:每经过一个传输轮次(即往返时延 RTT),cwnd 加 1,即线性规律增长。只要发送方判断网络出现拥塞,则令 ssthresh = cwnd / 2。然后令 cwnd=1,重新执行慢算法。

【注】传输轮次和往返时延的区别:

  • 传输轮次:发送一批报文段并收到它们的确认的时间。
  • 往返时延 RTT:开始发送一批报文段到开始发送下一批报文段的时间。

例如有以下传输过程:

传输轮次cwnd发送的 TCP 数据部分的序号算法备注
110 号慢开始初始时,cwnd = 1,ssthresh = 16
221 ~ 2 号慢开始
343 ~ 6 号慢开始
487 ~ 14 号慢开始
51615 ~ 30 号拥塞避免cwnd = ssthresh = 16
61731 ~ 47 号拥塞避免
71848 ~ 64 号拥塞避免
1324171 ~ 194 号拥塞避免重传计时器发生超时,说明网络拥塞,ssthresh = cwnd/2 = 12
141195 号慢开始cwnd 重新设置为 1
152196 ~ 197 号慢开始
164198 ~ 201 号慢开始
178202 ~ 209 号慢开始
1812210 ~ 221 号拥塞避免cwnd = 16 > ssthresh = 12,改用拥塞避免算法
1913222 ~ 234 号拥塞避免

慢开始和拥塞避免算法的实现过程如下图:

在这里插入图片描述

【注】慢开始和拥塞避免的含义:

  • “慢开始”是指一开始向网络注入的报文段少,而并不是指拥塞窗口 cwnd 的值增长速度慢。
  • “拥塞避免”也并非指完全能够避免拥塞,而是指在拥塞避免阶段将 cwnd 值控制为按线性规律增长,使网络比较不容易出现拥塞。

5.2 快重传和快恢复

快重传和快恢复是对慢开始和拥塞避免算法的改进。根据发送方的拥塞窗口 cwnd 的大小执行不同的算法:

  • 当 cwnd < ssthresh 时,若是首次传输,则使用慢开始算法;如果不是首次传输,则使用拥塞避免算法;
  • 当 cwnd > ssthresh 时,使用拥塞避免算法;
  • 当 cwnd = ssthresh 时,使用拥塞避免算法。

快重传算法:当发送方连续接收到三个冗余 ACK 报文时,直接重传对方尚未收到的报文段,而不必等待该报文段的重传计时器超时。

快恢复算法:当发送方连续接收到三个冗余 ACK 报文时,令 ssthresh = cwnd / 2,然后 cwnd 从该 ssthresh 开始线性增加。

例如有以下传输过程:

传输轮次cwnd发送的 TCP 数据部分的序号算法备注
110 号慢开始初始时,cwnd = 1,ssthresh = 16
221 ~ 2 号慢开始
343 ~ 6 号慢开始
487 ~ 14 号慢开始
51615 ~ 30 号拥塞避免cwnd = ssthresh = 16
61731 ~ 47 号拥塞避免
71848 ~ 64 号拥塞避免
1324171 ~ 194 号拥塞避免发送方连续收到三个冗余 ACK 报文,说明网络拥塞,ssthresh = cwnd/2 = 12
1412195 ~ 206 号拥塞避免cwnd 设置为 ssthresh = 12
1513207 ~ 219 号拥塞避免
1614220 ~ 233 号拥塞避免
1715234 ~ 248 号拥塞避免
1816249 ~ 264 号拥塞避免
1917265 ~ 281 号拥塞避免

快重传和快恢复算法的实现过程如下图:

在这里插入图片描述

需要注意,发送方的发送窗口由接收方的接收窗口和发送方的拥塞窗口两者的最小值所决定,即swnd = min(rwnd, cwnd)

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

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

相关文章

python数据可视化玩转Matplotlib subplot子图操作,四个子图(一包四),三个子图,子图拉伸

目录 一、创建子图 1.1 下图是绘制的子图&#xff1a; 1.2 代码释义&#xff1a; 二、绘制子图 2.1 代码引入 2.2 图形绘制 三、子图布局 3.1 子图布局说明 四、子图大小 4.1 子图大小调整 五、子图间距 5.1 子图代码调整 六、子图位置 6.1 代码引入 6.2 完整代码…

如何在 Windows10 下运行 Tensorflow 的目标检测?

前言 看过很多博主通过 Object Detection 实现了一些皮卡丘捕捉&#xff0c;二维码检测等诸多特定项的目标检测。而我跟着他们的案例来运行的时候&#xff0c;不是 Tensorflow 版本冲突&#xff0c;就是缺少什么包&#xff0c;还有是运行官方 object_detection_tutorial 不展示…

算法记录 | Day30 回溯算法

332.重新安排行程 思路&#xff1a; 1.确定回溯函数参数&#xff1a;定义全局遍历存放path&#xff0c; 2.终止条件&#xff1a;遍历完所有路径&#xff0c;机场个数&#xff0c;如果达到了&#xff08;航班数量1&#xff09;&#xff0c;即path的长度应当为字符串二维数组长…

教程 | 多通道fNIRS数据的预处理和平均(下)

前言 前文近红外数据的预处理和平均&#xff08;上&#xff09;提到fNIRS是一种评估氧和脱氧血红蛋白浓度变化的方法&#xff0c;可与fMRI相媲美。fNIRS的不足是它的空间分辨率比fMRI差&#xff0c;但其优点是有更高的时间分辨率&#xff0c;并允许测量无法通过fMRI扫描仪测试…

GPT-4 API 接口调用及价格分析

GPT-4 API 接口调用及价格分析 15日凌晨&#xff0c;OpenAI发布了万众期待的GPT-4&#xff01;新模型支持多模态&#xff0c;具备强大的识图能力&#xff0c;并且推理能力和回答准确性显著提高。在各种专业和学术基准测试上的表现都媲美甚至超过人类。难怪OpenAI CEO Sam Altm…

动态规划专题(明天继续)

动态规划求最大值&#xff1a; 题目描述 小蓝在一个 nn 行 mm 列的方格图中玩一个游戏。 开始时&#xff0c;小蓝站在方格图的左上角&#xff0c;即第 11 行第 11 列。 小蓝可以在方格图上走动&#xff0c;走动时&#xff0c;如果当前在第 rr 行第 cc 列&#xff0c;他不能…

ASIC-WORLD Verilog(3)第一个Verilog代码

写在前面 在自己准备写一些简单的verilog教程之前&#xff0c;参考了许多资料----asic-world网站的Verilog教程即是其一。这套教程写得极好&#xff0c;奈何没有中文&#xff0c;在下只好斗胆翻译过来&#xff08;加了自己的理解&#xff09;分享给大家。 这是网站原文&#xf…

Windows应急响应 -Windows日志排查,系统日志,Web应用日志,

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 Windows日志分析一、查看日志二、日志分类三、筛选日志四、事件ID1、安全日志1.1、登录类…

基于Java+SSM+Vue的旅游资源网站设计与实现【源码(完整源码请私聊)+论文+演示视频+包运行成功】

博主介绍&#xff1a;专注于Java技术领域和毕业项目实战 &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例&#xff08;200套&#xff09; 目录 一、效果演示 二、…

【从零开始学Skynet】实战篇《球球大作战》(八):login代码设计

现在来编写我们的第二个服务——登录服务&#xff0c;在编写此服务时&#xff0c;建议大家对照着如下所示的流程图来看&#xff0c;知晓各个方法的作用&#xff0c;写起来会简单许多。 1、登录协议 定义如下图所示的登录协议&#xff1a; 客户端需要发送玩家账号和密码&#x…

MyBatis 源码解析 面试题总结

MyBatis源码学习环境下载 文章目录1、工作原理1.1 初始化1.1.1 系统启动的时候&#xff0c;加载解析全局配置文件和相应的映射文件1.1.2 建造者模式帮助我们解决复杂对象的创建&#xff1a;1.2 处理SQL请求的流程1.2.1 通过sqlSession中提供的API方法来操作数据库1.2.2 获取接口…

UOS内核替换kylin内核

一、替换UOS内核 如果可以获取UOS的的ROOT权限, 跳过步骤一和二。 步骤一、配置环境 如果有UOS系统的机器,则不需要安装,跳到步骤二 。 如果没有UOS系统则需要下载, 下载UOS镜像:统信UOS生态社区 - 打造操作系统创新生态 ,下载专业版需要用户注册大概1~3天可以通过,…

HTML-form表单和提交

网络请求 在浏览器的URL中写入地址&#xff0c;点击回车访问时 浏览器会发送数据过去&#xff0c;本质上发送的是字符串 浏览器向后端发送请求时 GET请求【URL方法/表单提交】 现象&#xff1a;向后台传入数据&#xff0c;数据会拼接在URL上 搜索百度时&#xff1a; http…

十四、Pytorch实现RNN Classifier

一、项目需求 数据集&#xff1a;姓名和对应的国籍 要求&#xff1a;输入一个姓名&#xff0c;通过模型可以得到TA所属的国籍 数据集下载&#xff1a;name_country_datasets 二、思路步骤分析 ①准备数据集 将下载好的数据集解压&#xff0c;放到一个指定的位置&#xff0c…

文心一格小程序,AI绘画产品

文章目录AIGC什么是AI作画&#xff1f;Prompt文心一格文心一格小程序使用方法使用小程序进行AI绘图AIGC的未来发展结语AIGC AIGC&#xff08;AI Generated Content&#xff09;是指利用人工智能生成内容。是利用人工智能来生成你所需要的内容&#xff0c;GC的意思是创作内容。与…

samba介绍和使用

一. 介绍 Samba是一套使用SMB(Server Message Block)协议的应用程序, 通过支持这个协议, Samba允许Linux服务器与Windows系统之间进行通信,使跨平台的互访成为可能。 Samba采用C/S模式, 其工作机制是让NetBIOS( Windows 网上邻居的通信协议)和SMB两个协议运行于TCP/IP通…

【Obsidian】基础使用手册(包括如何将Obsidian页面设置为中文)

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于工具类软件的笔记 &#x1f236;本篇是Obsidian的基础使用 Obsidian的基础使用将页面设置为中文常用的默认快捷键常用的格式标题代码块表格字体样式列表任务列表官方下载地址&am…

中国电子学会2022年12月份青少年软件编程Python等级考试试卷六级真题(含答案)

一、单选题(共25题&#xff0c;共50分) 1.数据文件“abc.txt”中包含若干个英文单词&#xff0c;如图所示&#xff1a; 读取文件“abc.txt”中数据的Python程序段如下&#xff1a; file abc.txt word_b [] for word in open(file):if word[0:1] a and len(word)>4:wor…

ASP学生公寓管理系统的设计与实现

学生公寓是每一位在校学生生活、学习、相互交流的主要场所&#xff0c;如何提供一个良好的学生公寓的管理体系&#xff0c;对学校和同学而言至关重要。以往的学生公寓管理基本上还处于人工操作的阶段&#xff0c;随着计算机技术和网络技术的日益广泛应用&#xff0c;采用计算机…

Oracle基础部分三(视图、物化视图、序列、同义词、索引)

Oracle基础部分三(视图、物化视图、序列、索引&#xff09;1 视图1.1概述1.2 创建普通视图1.2.1 创建普通视图1.2.2 创建带检查约束的视图1.2.3 创建只读视图的创建与使用1.2.4 强制创建视图1.2.5 创建复杂视图1.2.5.1 多表关联1.2.5.2 分组聚合统计的复杂视图1.3 创建物化视图…