当前位置: 首页 > news >正文

TCP协议原理一

在这里插入图片描述

文章目录

  • 一、TCP协议
  • 二、TCP工作机制
    • 1.确认应答
    • 2.超时重传
    • 3.连接管理
      • 三次握手
      • 四次挥手

一、TCP协议

我们的TCP协议相比于UDP协议复杂不少,今天我们就来一起学习一下TCP协议报文和原理
在这里插入图片描述
首先我们报头第一行里的端口号和UDP的端口号是一致的,都是用两个字节来表示。
32位序号和32位确认序号: 在这里先不给大家解释,等会我们再将TCP确认应答原理时会给大家讲到。
4位首部长度: 正是因为这个首部长度存在,我们的TCP的报头长度是可变的,而我们的UDP报头长度是8个字节固定死的,首先我们需要明白,我们选项之前的长度是固定的20字节,而我们首部长度可以调节的就是选项长度,我们首部长度的单位是4字节,选项长度等于首部长度 - 20字节,如果我们的首部长度是6,那么TCP报头就是24字节(选项相当于是4字节)。
**保留(6位): ** 我们这里的保留六位是为了以后扩展考虑的,因为我们的网络协议是一件成本较高的事情,就拿UDP来说,报文长度是2字节,因此一个包最大是64KB,如果我们想让它兼容更大一些的长度,理论可行但是实际操作极高,但是如果我们引入了保留字,我们后面TCP引入了新功能就可以使用这些保留字,不仅对报头结构影响极小,而且老设备也不需要升级也可兼容。
在这里插入图片描述
这个我们在后面讲原理的时候会介绍到。
16位窗口大小,16位紧急指针: 这些我们在后面会介绍到,16位窗口和我们的滑动窗口和流量控制原理有关。
16位校验和: 和我们的UDP校验原理相同,CRC,MD5,SHA1
选项: 选项(option),这个是对TCP一些功能扩展和TCP一些属性进行解释说明的。

TCP报文 = TCP报头 + TCP载荷(payload),载荷也就是我们的数据。

二、TCP工作机制

我们的TCP相比于UDP是一个比较复杂的协议,也包含很多机制,我们主要学习10大核心机制

1.确认应答

TCP的特点中有可靠传输的特性,确认应答就是实现可靠传输的核心机制。大家还需要明白,我们这里的可靠指的不是我们发送方百分百能将数据发送到接收方,而是尽可能的发过去即使没有发过去我们的发送方也能够知道。
比如我们有这样一个场景,一个宿舍中的A同学和B同学要通信。
在这里插入图片描述
我们这里的不上就称之为"应答报文",也叫ack(acknowledge).
当A同学收到不上的时候,就可以知道我们上号这个消息B同学已经看到了(证明没有丢包),如果我们一段时间后没有收到ack证明我们的消息大概率不见了(也就是丢包)。
TCP可靠传输主要就是靠这个确认应答机制来保证的,我们A给B发消息,B收到之后就会返回一个ack,A收到这个应答之后,就证明我们的数据顺利到达了(没有丢包)。
上述的通信是比较简单的单一通信,我们来看一个稍微复杂一点的。
在这里插入图片描述
同学A可能会连续发多条消息,发第二条消息时,不需要等待第一个消息的应答,我们的B同学收到消息立马回复,我们在网络通信时,很有可能发生后发先至,因为我们的网络环境是错综复杂的,很有可能发的晚的消息先到的情况。
上面的情况是正常的情况,那么我们来看一个不正常的情况。
在这里插入图片描述
因为这种后发先至的情况,我先收到了上,后收到了不上,这样我们的应答错乱后表示的含义就截然不同了。
首先网络上后发先至这种情况是客观存在无法避免的,我们应该考虑的是如何应对这种情况所带来的异义。
我们采取的办法是给传输的数据和应答报文编号。
在这里插入图片描述
当我们引入序号后,即使出现先发后至的情况,消息的顺序即使乱了,我们通过序号也可以明确将每条应答报文与其对应了。

在这里插入图片描述
我们任何一条数据(包括应答报文)都是有序号的,确认序号只有应答报文有,是否为应答报文取决于ACK这个标志位是否为1,如果为1证明是应答报文,如果是0表示不是应答报文。
我们实际上的TCP序号并不是简单的1,2这种方式编号,我们TCP是面向字节流的,我们的TCP序号也是按照字节来编号的。
在这里插入图片描述
假设我们的一条数据长度是1000个字节,我们的数据是由1开始的,此时我们第一个字节编号就是1,第二个字节编号就是2依次,但是我们前1000个字节都是属于同一TCP报文,因此我们TCP报头里记录的序号就是第一个字节的序号,也就是1。
当我们发送第二条数据,序号就是1001了,我们的TCP字节序号是依次增加的,起始字节序号是上一个数据的最后一个字节,我们TCP报头只需写TCP头一个字节序号即可,在根据TCP报文长度即可知道TCP的每一个字节的序号。
在这里插入图片描述
我们应答报文里的确认序号中的1001就是刚才尾字节1000基础+1的结果,1001所表示的含义有两个:
1.小于1001的数据都已经确认收到了
2.发送方接下来应该从1001这个序号开始发送数据

结论: TCP可靠传输最主要是通过确认应答机制保证的,我们不仅可以让发送方清楚的知道是否传输成功,并且通过序号和确认序号对多组数据进行了详细的区分。

2.超时重传

我们刚才在讨论确认应答的时候,只是在一个理想的传输场景下讨论的,那如果在传输过程丢包了呢?
首先丢包有两种情况: 1. 发送的数据丢了 2.应答报文ack丢了,站在我峨嵋你发送方的角度,这两种情况都认为是丢包了,正在因为这种丢包的可能性发送,我们TCP就引入了重传机制,我们在丢包的时候就要重新发一遍相同的数据,那么如何判断是丢包还是ack正在返回路上?
我们TCP直接引入一个时间阈值,在发送数据后,就会开始倒计时等待ack,如果时间超过时间阈值也没收到ack,统一认为丢包。
超时重传: 接收方在一定时间没有响应,发送方就重新发送一份相同的数据。
时间阈值: 超时时间具体是多少,这个我们不具体讨论是多少,根据场景业务而定,是可配置的。
在这里插入图片描述
这种情况比较形象,发送方发送的数据丢包了,在一定的时间后重新传输一次,然后收到ack之后就视为一次成功的传输。
在这里插入图片描述
但是当ack丢包时,对于我们主机B而言,1 -1000的数据接收了两次,这种情况就比较麻烦了,但是我们TCP对于重复的数据传输,具有去重功能,我们TCP存在一个发送缓冲区和接收缓冲区接收缓冲区相当于是接收方操作系统内核的一段内存,我们在网络编程的时候学习的socket的对象中都有一个接收缓冲区,我们主机B的网卡接收到数据之后,将数据放到主机soekct对象对应的接收缓冲区中,我们可以将这个缓冲区想象成一个优先级阻塞队列,我们根据序号可以将数据进行去重排序,如果有相同的数据就将后到的数据丢弃,排序就可以应对我们的后发先至情况。
结论: 由于我们去重与排序机制的存在,发送方只要发现在一定时间阈值内ack没有到达,就会重新发一份数据,数据即使重复乱序,我们的接收方都可以处理,去重和排序机制都依赖TCP报头的序号。
相信有一些善于思考同学又会问了,要是我们重传的数据有丢包了呢?
首先我们丢包是一件概率比较低的事件,连续重传丢包的概率更低,因此我们在重传到一定次数后,就不会再死磕,就会认为网络出现故障,TCP就会尝试重置连接,如果重置还是无效,就会彻底断开连接。
TCP的可靠传输: TCP的可靠传输通过 确认应答 和 超时重传机制保证的,两者相互配合,共同保证了TCP的可靠性。

3.连接管理

连接在不同的场景表示不同的含义,在我们TCP协议这里,表示的是维护一些信息(四元组)的空间。
在这里插入图片描述
我们TCP建立连接并不是指通过一根线将两者连接起来,而是将这两部分信息维护好,简单来说A要能通过这部分信息找到B,B能通过这部分信息找到B,我们称保存好这部分信息的空间为连接,删除这部分信息,称之为断开。

三次握手

我们仍然拿出A同学和B同学,刚上大学A同学和B同学想通过游戏加深一下感情,但是又不知道对方玩什么游戏,于是有了以下的场景:
在这里插入图片描述
首先A向B发出了询问,然后B回应了A,此时双方都知道了B玩王者农药,但想要一起组队玩王者农药,B需要明确A是否也玩,于是B又发送了一次请求,这时候A知道了B玩,B知道了A也玩,这个时候他们才能一起上号打游戏,相当于建立连接成功。
我们把上述过程的每次通信形象的称为一次挥手,但实际上我们有两次是可以合并成一次的。
在这里插入图片描述
我们所谓的三次握手的本质上是四次交互,双方各自需要发送一个建立的请求,然后收到一个ack,实际上是有四次的信息交互,但是中间两次是可以合并的,因此就构成了三次握手
如果不合并,可以吗?
不可以,如果我们从三次变成四次就会多封装分用一次,成本更高,就好比宿舍倒垃圾,本来可以一个大袋子一次性倒,一个是用两个小袋子分两次倒。

两次握手可以完成建立连接吗?
在这里插入图片描述
如果少了最后一次握手,站在A的角度,他已经知道了B玩王者农药,但是站在B的角度,他不知道A玩不玩王者农药。
有的同学可能会说,A能问你A肯定玩呀,虽然这个情况也有可能,但是TCP这里不适用,因为三次握手还有一个重要作用:验证通信双方各自的发送和接收能力是否正常
比如我们两个人在打王者农药,组队开麦,A和B能够顺利交流,需要有两个保证,就是A和B的麦和音响都是好的。
在这里插入图片描述
第一次通信,当B听到"你可以听到吗?" B知道了 A的麦是正常的,B的音响是正常的。 A什么都不知道。
第二次通信,当A听到"可以,你呢", B知道了A的麦是正常的,B的音响是正常的。A知道了A的麦和音响以及B的麦和音响都是正常的。
第二次通信之后,A以及知道了双方都满足了条件,但B知道的信息还不全,需要进行第三次通信。
第三次通信,当B听到"可以"时,证明我们A和B都知道了自己的麦和音响和对方的麦和音响是正常的,可以正常交流了。
三次握手的作用:
1.让通信双方建立相互的认可
2.验证双方的发送与接受能力是否正常
3.在握手的过程,双方协商一些参数。
在这里插入图片描述
我们客户端主动给服务器发送的建立连接请求称为SYN同步报文段.
在这里插入图片描述
在这里插入图片描述
这些都是TCP的状态,不同的TCP状态主要体现我们的TCP在干什么,三次握手中我们主要学习两个重要状态:
1.LISTEN服务器状态:表示我们的服务器以及转杯就绪,随时可以与客户端建立连接。
2.ESTABLISHED::这个状态我们客户端服务器都有,当我们进行两次握手后,我们的客户端就已经认为进行成功建立连接,于是进入了ESTABLISHED状态,我们的服务器只有当三次握手进行完毕后才认为成功的建立了连接,进入了ESTABLISHED状态,当我们成功建立连接之后就可以进行通信了。
上述描述的三次握手一次性记住不太容易,大家需要记住主要的流程:
在这里插入图片描述

四次挥手

握手和挥手都是形象的叫法,指的是客户端服务器之间的交互,四次挥手指的是通信双方给对方发一个断开连接的请求,在各自给对方一个回应。
这里我们同样是A同学和B同学打了一下午王者农药输了一下午:
在这里插入图片描述
这里需要注意,我们在断开连接的过程中,中间两次通常是不能合并的。
在这里插入图片描述
我们三次握手之所以中间两次可以合并,是因为它两是属于同一时机的,具体来说,三次握手的三次交互过程是系统内核完成的,服务器内核收到了syn之后会立即发送ack也会立即发送syn。
这就好比于我们在同一家店铺买东西,我们的三次握手中间的两次就相当于是同一时间段在一家店铺买的两样东西,所以可以通过一个包裹发送这两样东西,而我们四次挥手中间两次,则是在不同的天数买的,比如2月9号买了个牙刷,2月11买了个牙膏,则不能够通过一个包裹,必须通过两个包裹发送。
在这里插入图片描述
我们的FIN发起不是有内核控制的,而是我们客户端调用socket的close方法(进程退出)才会触发FIN,我们服务器的ack是有内核控制的,收到FIN之后立即返回ack,而我们服务器的FIN是我们服务器执行到socket的close方法(或进程退出)才会触发FIN。
因此大家注意到,我们服务器ack和FIN之间只有一个时间差的,而这个时间差的大小由我们的代码所决定,我们可以发开我们之前写的TCP客户端服务器回显服务器看一看。
在这里插入图片描述
我们可以看到这里的break决定着循环结束,而这里的break能够执行到取决于我们的hasNext为false,因就是流对象读到了EOF(文件结束标记),这里能读到EOF是因为内核收到了客户端发送来的FIN数据报,虽然我们的客户端程序没有显示的写close方法,但是当我们客户端进行退出的时候也会执行socket close会触发FIN。
在这里插入图片描述
当我们的循环执行结束之后,会执行到finally里的close方法,相当于我们服务器给客户端发送的FIN,我们上述代码里循环结束后立即FIN,ack与FIN之间的时间间隔相对就比较短,也就有可能包裹成一个,但是如果时间间隔比较长就不可以了,比如这样:
在这里插入图片描述
我们的代码在close之前进行了一系列操作,这样我们的FIN和ack时间间隔就比较久了,也就无法合并成一个了。
在这里插入图片描述
同样的我们断开连接中的FIN在报头中也有标志,FIN为1证明是断开连接的请求报文。
在这里插入图片描述
我们TCP四次挥手当中也有许多状态,我们这里重点学习两个TCP状态:
1.CLOSE_WAIT: 出现在被动连接的一方,等待关闭(等待socket调用close方法),大家需要注意的是,建立连接的过程中一定是客户端主动发起请求,断开连接可能是客户端也可能是服务器。
TIME_WAIT: 出现在主动发起断开请求的一方法,这里我们客户端是主动断开的一方,当客户端进行TIME_WAIT状态时,客户端认为四次挥手已经挥完了,这里的TIME_WAIT要保持TCP状态保持一会不要立即释放。
为什么我们的TIME_WAIT要等待一会不要立即释放连接?
因为我们最后一个ack虽然已经发出去了,但是仅仅是发出去了,到没到我们得打一个问号?万一这个ack丢包了呢,我们TIME_WAIT会在发完ack之后等,如果没有接收到重传的FIN,就认为最后一个ack没有丢包然后释放连接。
在这里插入图片描述
站在我们服务器角度来说,当我们ack发送了之后,进入TIME_WAIT状态时,相当于是四次挥手已经完成了一样,没有客户端的活了,虽然看起来完了,但是是建立在一切顺利的前提下,如果出现了丢包等情况,客户端就没有完成工作,我们的TIME_WAIT就是这些工作但的保证。
那么TIME_WAIT保持多久,才真正释放呢?
我们这里等待的时间为2MSL ,如果TIME_WAIT维持了2MSL都没用收到重传的FIN,就认为我们的ack顺利到达了。
那么MSL指的又是什么呢?
指的是,互联网上两个结点之间,消耗传输时间的最大时间。至于这个MSL通常大概是60s,在这里大家需要注意,我们这里的MSL无论如何定义都不可避免一些特殊情况,因此我们的MSL相当于是一个经验值,绝大多数情况下数据包传输时间都不会超过MSL。

相关文章:

TCP协议原理一

文章目录一、TCP协议二、TCP工作机制1.确认应答2.超时重传3.连接管理三次握手四次挥手一、TCP协议 我们的TCP协议相比于UDP协议复杂不少,今天我们就来一起学习一下TCP协议报文和原理 首先我们报头第一行里的端口号和UDP的端口号是一致的,都是用两个字节…...

【黑马SpringCloud(6)】Sentinel解决雪崩问题

微服务保护雪崩问题服务保护技术Sentinel微服务整合Sentinel流量控制簇点链路入门练习流控模式关联链路流控效果Warm Up排队等待热点参数限流隔离和降级FeignClient整合Sentinel线程隔离(舱壁模式)实现线程隔离熔断降级慢调用异常比例/异常数授权规则获取origin给网关添加请求头…...

微信小程序 java springboot招聘求职应聘简历系统

应聘系统是基于微信小程序,java编程语言,mysql数据库,springboot框架,idea工具开发,本系统主要分为用户,企业,管理员三个角色,用户注册登陆小程序,查看应聘分类&#xff…...

亿级高并发电商项目-- 实战篇 --万达商城项目 四(Dashboard服务、设置统一返回格式与异常处理、Postman测试接口 )

专栏:高并发---前后端分布式项目 👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、…...

为什么这11道JVM面试题这么重要(附答案)

本文内容整理自 博学谷狂野架构师 运行时数据区都包含什么 虚拟机的基础面试题 程序计数器Java 虚拟机栈本地方法栈Java 堆方法区 程序计数器 程序计数器是线程私有的,并且是JVM中唯一不会溢出的区域,用来保存线程切换时的执行行数 程序计数器&#xff…...

概率统计之概率篇

概率统计之概率篇 一 随机变量及其四种研究方法 为了更深入地研究随机现象,需要把随机试验的结果数量化,也就是要引进随机变量来描述随机试验的结果。 一般地,把表示随机现象的各种结果或描述随机事件的变量叫做随机变量。随机变量通常用大…...

综合项目 旅游网 【5.旅游线路收藏功能】

分析判断当前登录用户是否收藏过该线路当页面加载完成后,发送ajax请求,获取用户是否收藏的标记根据标记,展示不同的按钮样式编写代码后台代码RouteServlet/*** 判断当前登录用户是否收藏过该路线*/ public void isFavorite(HttpServletReques…...

【ArcGIS Pro二次开发】(3):UI管理_显示隐藏Tab、Group、Control等控件

在ArcGIS Pro工作中,有时候会涉及到工具栏UI的管理,比如,打开模型构建器时,工具栏才会出现新的选项卡(Tab)【ModelBuilder】,工程未做更改,则【保存】按钮显示灰色不可用。 下面以一个小例子来学习一下。 一…...

Spring Boot开发实战——echarts图标填充数据

echarts模块的导入 先看看成品吧! 有的图标的数据用了一些计算框架不是直接查数据库所以有点慢。 ok!😃 上正文,接上节Spring boot项目开发实战——(LayUI实现前后端数据交换与定义方法渲染数据)讲解了一般…...

李达聪老师:互联网时代的B2B品牌如何塑造

李达聪老师:互联网时代的B2B品牌如何塑造互联网时代企业对企业的品牌如何塑造?互联网时代信息传播速度加快,并且各大新品牌就如春天的竹笋涌出,有的昙花一现,有的趁着时代的红利乘胜追击占领市场,建立品牌。有的成为一…...

javaEE 初阶 — 连接管理机制

文章目录连接管理机制1. 建立连接(三次握手)2. 断开连接(四次挥手)TCP 的工作机制确认应答机制 超时重传机制 连接管理机制 比如 主机A 的空间存储了 主机B 的 ip 和 端口,主机B 的空间存储了 主机A 的 ip 和 端口。…...

40个改变你编程技能的小技巧!

40个改变编程技能的小技巧 1、将大块代码分解成小函数 2、今日事今日毕,如果没毕,就留到明天。 如果下班之前还没有解决的问题,那么你需要做的,就是关闭电脑,把它留到明天。 中途不要再想着问题了! 3、…...

iTOP3588开发板直连电脑配置方法(无线上网)配置主机IP

首先使用网线连接好主机和开发板,在没有上电的情况下,可以看到以太网显示网络电缆 被拔出,如下图所示: 当开发板上电以后,开发板网卡与笔记本电脑的网卡会连接,如下图所示: 然后右键点击以太网…...

压电陶瓷换能器导纳圆图公式推导及匹配

压电陶瓷换能器的等效电路图如下图所示,分为左右两个部分左边的电容和电阻并联构成了电路的静态支路,被称为静态电容,可以由电表很方便的测量得到,这部分的参数是由换能器的电学参数决定的。右边的串联构成了动态支路,…...

设计模式C++实现11:观察者模式

参考大话设计模式; 详细内容参见大话设计模式一书第十四章,该书使用C#实现,本实验通过C语言实现。 观察者模式又叫做发布-订阅(Publish/Subscribe)模式。 观察者模式定义了一种一对多的依赖关系,让多个观察…...

l1和l2接口如何进行编写?一定要掌握这几个元素

在这个大数据时代,很多地方都需要用到l1和l2接口,l1和l2接口在应用程序与数据库之间起着桥梁的作用,是实现数据的整合与共享的重要帮手。 l1和l2接口适用于各行各业,应用场景的不断拓展,l1和l2接口的发展也兴起&#…...

GAMES101作业7及课程总结(重点实现多线程加速,微表面模型材质)

目录闲言碎语最终全部效果展示(均为10241024512ssp)课程总结与理解(Path Tracing)框架梳理任务一:迁移相关代码任务二:实现path tracing任务三:多线程加速(包括其他加速的小trick&am…...

面试题(二十四)数据结构与算法

9.1哈希 请谈一谈,hashCode() 和equals() 方法的重要性体现在什么地方? 考察点:JAVA哈希表 参考回答: Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。…...

【HAL库】STM32CubeMX开发----STM32F407----Uart串口接收空闲中断

一、Uart串口接收空闲中断----详解 首先介绍串口通信的数据传输方式,这样后面的Uart串口空闲中断能更好的理解。 Uart串口通信----数据传输方式 串口通信的数据由发送设备通过自身的TXD接口传输到接收设备得RXD接口。 一个字符一个字符地传输,每个字符…...

Qt_文件操作

本文包含以下内容: 文件操作 基本介绍:ini文件:csv文件:代码功能文件读写:1.1 读取文件1.1.1按行读取1.1.2整体读取1.2 写入文件2. 文件信息读取3. 文件夹的创建4. 获取文件夹下所有的文件5. 获取文件夹及子文件夹下所有的文件用树的方式在界面显示文件夹目录基本介绍: …...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...