ModbusTcp和ModbusRtu全面理解

2024-02-27 08:30

本文主要是介绍ModbusTcp和ModbusRtu全面理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、何为Modbus通信协议

1.1 Modbus基本介绍

        Modbus是一种通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式
         Modbus协议介绍:Modbus是 OSI 模型第 7 层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信。包括了ASCII、RTU、TCP三种;

  •  Modbus RTU与Modbus ASCII均为串行传输方式。其中,Modbus RTU采用二进制表现形式以及紧凑数据结构,通信效率较高,应用比较广泛。而Modbus ASCII采用ASCII码传输,并且利用特殊字符作为其字节的开始与结束标识,其传输效率要远远低于Modbus RTU协议。
  • Modbus TCP是通过工业以太网TCP/IP网络传输的Modbus通信。Modbus数据传输提供了连接在以太网 TCP/IP网络上的客户机与服务器之间的实时通讯。

1.2 Modbus的工作方式请求/应答

        Modbus是使用主从关系实现的请求 - 响应协议。在主从关系中,通信总是成对发生,一个设备必须发起请求,然后等待响应,并且发起设备(主设备)负责发起每次交互。通常,主设备是人机界面(HMI)或监控和数据采集(SCADA)系统,从设备是传感器、可编程逻辑控制器(PLC)或可编程自动化控制器(PAC)。这些请求和响应的内容以及发送这些消息的网络层由协议的不同层来定义。

  • Modbus的工作方式是请求/应答,每次通讯都是主站先发送指令,可以是广播,或是向特定从站的单播;从站响应指令,并按要求应答,或者报告异常。当主站不发送请求时,从站不会自己发出数据,从站和从站之间不能直接通讯 。

1.3 Modbus通讯方式

        MODBUS 协议允许在各种网络体系结构内进行简单通信。每种设备(PLC、HMI、控制面板、驱动程序、动作控制、输入/输出设备)都能使用 MODBUS协议来启动远程操作。
Modbus有下列三种通信方式:

  • 以太网:对应的通信模式是Modbus TCP/IP
  • 异步串行传输(各种介质如有线RS-232-/422/485/;光纤、无线等):对应的通信模式是Modbus RTU或Modbus ASCII
  • 高速令牌传递网络:对应的通信模式是Modbus PLUS

二、功能码和寄存器地址

2.1 功能码分类

一共有三类Modbus功能码:公共功能码、用户定义功能码、保留功能码

1)公共功能码
是较好地被定义的功能码、保证是唯一的、MODBUS 组织可改变的、公开证明的、具有可用的一致性测试、MB IETF RFC 中证明的、包含已被定义的公共指配功能码和未来使用的未指配保留供功能码
2)用户定义功能码
有两个用户定义功能码的定义范围,即 65 至 72 和十进制 100 至 110、用户没有 MODBUS 组织的任何批准就可以选择和实现一个功能码、不能保证被选功能码的使用是唯一的、如果用户要重新设置功能作为一个公共功能码,那么用户必须启动 RFC,以便将改变引入、公共分类中,并且指配一个新的公共功能码。
3)保留功能码
一些公司对传统产品通常使用的功能码,并且对公共使用是无效的功能码

2.2 常用功能码

常用功能码:十六进制的

  • 读取输出线圈 0x01
  • 读取输入线圈 0x02
  • 读取输出寄存器 0x03
  • 读取输入寄存器 0x04
  • 写入单个输出线圈 0x05
  • 写入多个输出线圈 0x0F
  • 写入单个输出寄存器 0x06
  • 写入多个输出寄存器 0x10
  • 注意:H03和H04的区别:两个都是读取寄存器,用H03读取的寄存器可以写入,用H04读取的寄存器,不能在用H06写入;(通讯设备厂家读取功能码有要求用H03还是H04)
功能码描述说明MOUBUS地址异常功能码(+ 0×80)
1读取输出线圈位操作00001 ~ 099990×81
2读取输入线圈位操作10001 ~ 199990×82
3读取输出寄存器字操作40001 ~ 499990×83
4读取输入寄存器字操作30001 ~ 399990×84
5写入单个输出线圈位操作00001 ~ 099990×85
6写入单个输出寄存器字操作40001 ~ 499990×86
0F写入多个输出线圈位操作00001 ~ 099990×8F
10写入多个输出寄存器字操作40001 ~ 499990×90

2.3 寄存器地址

        通常Modbus地址由5位数字组成,包括起始的数据类型代号,以及后面的偏移地址。

Modbus地址模型的编号从1开始。

由于每一种数据都最大支持65536个元素,因此理论上,
对于线圈型数据来说,其地址范围为:000001~065536;
离散量输入,其地址范围为:100001~165536;
输入寄存器,其地址范围为:300001~365536;
保持寄存器,其地址范围为:400001~465536;

由于65536是比较大的数值,实际应用一般不需要这么大的存储区,因此PLC厂家普遍采用的是10000以内的地址范围,即:
线圈地址范围:00001~09999;
离散量输入地址范围:10001~19999;
输入寄存器地址范围:30001~39999;
保持寄存器地址范围:40001~49999;

国内汇川就用 全地址,000001~065536

Modbus Master协议库支持如下地址:

MOUBUS地址含义访问方式
00001~09999离散量输入(Discrete Input)只读
10001~19999线圈(Coils);读/写
30001~39999输入寄存器(Input registers);只读
40001~49999保持寄存器(Holding registers);读/写

        由上表可知,Modbus通讯的地址是从1开始的,如果遇到从机设备的寄存器编号从0开始,那么就需要考虑给通讯地址加1处理。

三、Modbus RTU 数据帧结构

3.1 Modbus RTU 数据帧结构

        RTU协议中的指令由地址码(一个字节),功能码(一个字节),起始地址(两个字节),数据(N个字节),校验码(两个字节)五个部分组成。数据由数据长度(两个字节,表示的是寄存器个数,假定为M)和数据正文(M乘以2个字节)组成。

从站地址:一个字节,作用是索引
功能码:一个字节,表明读写功能
数据:通信所传输的数据,可以是多字节
校验:判断接收的数据在传输过程中是否有损失,两个字节

3.2 Modbus RTU示例

3.2.1 读输出线圈【0x01功能码】

  • 发送报文格式:
从站地址功能码起始地址(高位)起始地址(低位)数量(高位)数量(低位)校验码(低位)校验码(高位)
0x030x010x000x130x000x1BXXXX

含义:
目标所在从站:0x03(3号)
命令:0x01(读线圈状态)
寄存器种类:线圈状态
目标起始索引地址:0x0013(索引地址 = 19)(16进制13,转换索引地址,十进制19)
目标起始PLC地址: 00001 + 19 = 00020(线圈状态PLC地址范围:00001-09999)
读取线圈数量:0x1B(1B = 27个,即27bit数据)
目标线圈范围:00020 - 00046(从00020开始27个线圈)
校验码:XXXX

  • 从机正常应答格式
从站地址功能码字节计数字节一字节二字节三字节四校验码(低位)校验码(高位)
0x030x010x040xCD0x6B0xB20x05YYYY

含义:返回从3号从站读取的共4个字节的数据,数据为:0xCD、0x6B、0xB2、0x05(为了举例子暂时编的),校验码为YYYY。

补充:由于读取的是线圈(bit),若读取的个数不为8的倍数,比如这次读27bit,则取整数字节4字节32bit返回,剩余5bit用0补全。

3.2.2. 读保持寄存器 【0x03功能码】

请求帧格式

从站地址功能码起始地址(高位)起始地址(低位)数量(高位)数量(低位)校验码(低位)校验码(高位)
0x030x030x000x060x000x02XXXX

含义:
目标所在从站:0x03(3号)
命令:0x03(读保持寄存器)
寄存器种类:保持寄存器
目标起始索引地址:0x0006(索引地址 = 6)
目标起始PLC地址: 40001 + 6 = 40007(保持寄存器PLC地址范围:40001-49999)
读取寄存器数量:0x02(02 = 2个,即2×2byte = 4byte数据)(一个寄存器为2字节)
目标线圈范围:40007-40008(从40007开始2个寄存器)
校验码:XXXX

正常应答帧格式

从站地址功能码字节计数字节一(高位)字节一(低位)字节二(高位)字节二(低位)校验码(低位)校验码(高位)
0x030x030x020xA10x050x040xCDYYYY

含义:返回从3号从站读取的共2个寄存器的数据,数据为:0xA105(40007上的数据)、0x04CD(40008上的数据)(为了举例子暂时编的),校验码为YYYY。

3.2.3. 读取输入寄存器持 【0x04功能码】

  • 发送报文格式
从站地址功能码起始(高)起始(低)数量(高)数量(低)校验码
0x010x040x000x6B0x000x02XXXX

发送报文含义:读取1号从站输入寄存器,起始地址为0x6B=107,对应地址为30108,寄存器数量为0x02=2,即读取1号从站输入寄存器,地址从30108-30109,共两个寄存器

  • 返回报文格式
从站地址功能码字节计数1高1低2高2低校验
0x010x040x040x020x2B0x010x06XXXX

返回报文含义:返回1号从站输入寄存器30108-30109,共2个寄存器的数值,返回字节数为4个,分别为02、2B、01、06,30108对应数值为0x022B,30109对应的数值为0x0106

3.2.4 写入单个输出线圈【0x05功能码】

  • 发送报文格式
从站地址功能码线圈(高)线圈(低)断通标志断通标志校验
0x010x050x000xAC0xFF0x00XXXX

发送报文含义:预置1号从站单个线圈的值,线圈地址为0x00AC=172,对应地址为00173,断通标志0xFF表示置位,0x0000表示复位,即置位1号从站输出线圈00173

  • 返回报文格式
从站地址功能码线圈(高)线圈(低)断通标志断通标志校验
0x010x050x000xAC0xFF0x00XXXX

返回报文含义:预置单输出线圈原报文返回

3.2.5 写入单个输出寄存器【0x06功能码】

  • 发送报文格式如下:
从站地址功能码寄存器高寄存器低写入值高写入值低校验
0x010x060x000x870x030x9EXXXX

发送报文含义:预置1号从站单个输出寄存器的值,寄存器地址为0x0087=135,对应地址为40136,写入值为0x039E,即预置1号从站输出寄存器40136值为0x039E。

  • 返回报文格式如下:
从站地址功能码寄存器高寄存器低写入值高写入值低校验
0x010x060x000x870x030x9EXXXX

返回报文含义:预置单输出寄存器原报文返回。

3.2.6 写多个线圈【0x0f功能码】

请求帧格式

从站地址功能码起始地址(高位)起始地址(低位)数量(高位)数量(低位)字节数字节一字节二字节三校验码(低位)校验码(高位)
0x010x0f0x000x130x000x150x030x120x1A0x04XXXX

含义:
目标所在从站:0x01(1号)
命令:0x0f(写多个线圈)
寄存器种类:线圈
目标起始索引地址:0x0013(索引地址 = 19)
目标起始PLC地址: 00001 + 19 = 00020(线圈状态PLC地址范围:00001-09999)
写入线圈数量:0x15(0x15 = 21bit数据)
实际写入线圈数量:21bit + 3bit = 24bit = 3byte(只能
目标线圈范围:00020-00040(从00020开始21个线圈)
字节一的值:0x12(0x12 = 18 = 0001 0010)
字节二的值:0x1A(0x1A = 26 = 0001 1010)
字节三的值:0xAC(0x04 = 4 = 0000 0100)(最高三位为补0)
校验码:XXXX

补充:若写入的线圈个数不为8的倍数,则高位补0使其字节数为整数。

正常应答帧格式(在原报文基础上除去字节数和具体字节并加上当前校验码)

从站地址功能码起始地址(高位)起始地址(低位)数量(高位)数量(低位)校验码(低位)校验码(高位)
0x010x0f0x000x130x000x15YYYY

含义:向1号从站起始地址为00020处写入21个线圈的值成功,校验码为YYYY。

3.2.7 写多个保持寄存器【 0x10功能码】

请求帧格式

从站地址功能码起始地址(高位)起始地址(低位)数量(高位)数量(低位)字节数字节校验码(低位)校验码(高位)
0x010x100x000x530x000x020x040x13141A1BXXXX

含义:目标所在从站:0x01(1号)
命令:0x10(写多个保持寄存器)
寄存器种类:保持寄存器
目标起始索引地址:0x0053(索引地址 = 83)
目标起始PLC地址: 40001 + 83 = 40084(线圈状态PLC地址范围:40001-49999)
写入寄存器数量:0x02(02 = 2个,即2×2byte = 4byte数据)(一个寄存器为2字节)
目标寄存器范围:40084-40085(从40084开始2个保持寄存器)
写入字节数:0x04(4个)
写入字节内容:0x13141A1B(40084保持寄存器写入0x1314 = 0001 0011 0001 0100 ,40085保持寄存器写入0x1A1B = 0001 1010 0001 1011)
校验码:XXXX

正常应答帧格式(在原报文基础上除去字节数和具体字节并加上当前校验码)

从站地址功能码起始地址(高位)起始地址(低位)数量(高位)数量(低位)校验码(低位)校验码(高位)
0x010x100x000x530x000x02YYYY

含义:向1号从站的40084位置开始写入两个保持寄存器成功,校验码为YYYY。

3.3 ModbusRTU如何判断开始与结束

         整个报文帧必须以连续的字符流发送。如果两个字符之间的空闲间隔大于 1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃 
        ModbusRTU协议中,需要用时间间隔来判断一帧报文的开始和结束,协议规定的时间为3.5个字符周期。在一帧报文开始前,必须有大于3.5个字符周期的空闲时间,一帧报文结束后,也必须要有3.5个字符周期的空闲时间,否则就会出现粘包的请况。3.5个字符周期是一个具体时间,与波特率有

关完整性判断:用1.5个字符时间判断帧的完整性,如果两个字符之间的空闲间隔大于1.5个字符时间,那么认为报文帧不完整,接收站丢弃这个报文帧。

 帧校验(CRC循环冗余校验,2字节,检验整个报文内容)
发送方计算CRC的值并附加到帧尾,接收报文的过程中,接收设备重新计算CRC的值,并将计算的结果和接收到的CRC比较;若不相等,则产生了错误。

3.4 ModbusASCII传输模式


1)ModbusRTU与ModbusASCII在报文数据发送格式上几乎一样,但也存在一些区别,具体体现在:

ModbusASCII有开始字符和结束字符(CR LF),可以作为一帧数据开始和结束的标志,而ModbusRTU没有这样的标。
两者校验方式不同,ModbusRTU是CRC循环冗余校验,ModbusASCII是LCR纵向冗余校验。
在Modbus标准中,RTU是必须要求的,而ASCII是可选项,即作为一个Modbus通信设备可以只支持RTU,也可以同时支持RTU和ASCII,但不能只支持ASCII。

用两个ASCII码字符发送报文中的一个8位字节,当通信链路或者设备不能满足RTU模式的定时管理要求时使用。
编码系统:十六进制,ASCII字符0-9,A-F,报文中每个ASCII字符表示一个十六进制字符
字节格式(10位)

  • 有校验:1个起始位,7个数据位,1个奇偶校验位,1个停止位
  • 无校验:1个起始位,7个数据位,2个停止位

串行发送字符:从左到右:最低有效位(LSB)…最高有效位(MSB)
校验(奇校验ODD、偶校验EVEN和无校验NONE)

  • 默认校验模式必须是偶校验,为了保证和其他产品的兼容性,建议使用无校验。
  • 如果使用无校验,那么多附加一个停止位来满足定长10位异步字符。

帧格式(最大513字节)

起始地址功能码数据LRC校验结束
1字符’:'冒号2字符2字符0-2×252字符2字符2字符(回车换行CR,LF)
  1. 一个报文必须以一个冒号(:)字符(十六进制ASCII 3A)作为起始,以回车换行(CRLF)(十六进制ASCII 0D和0A)作为结束。
  2. 报文中字符间时间间隔不能超过1s,除非配置了更长时间的超时,例如广域网应用可以要求4-5s超时,若超时,则表示已经出现错误。
  • 帧校验(LRC纵向冗余校验)
    • 校验内容不包括起始符和结束符
    • 对报文中除起始符和结束符外的所有连续的8位字节相加,忽略任何进位,然后求其二进制补码得到LRC
    • LRC的结果也被编码为2个ASCII码字符。

四、 Modbus TCP 数据帧结构

4.1 ModbusTCP介绍

        Modbus TCP协议是在Modbus RTU协议上加入MBAP(ModbusApplication Protocol Header)报文头,由于TCP是基于可靠连接的服务,所以在Modbus TCP协议中没有CRC校验,所有的Modbus TCPADU的发送和接收都是使用TCP传输控制协议,Modbus TCP/IP服务器端通常使用端口502作为接收报文的端口, IANA(Internet Assigned Numbers Authority,互联网编号分配管理机构)给Modbus协议赋予TCP端口号为502,这是目前在仪表与自动化行业中唯一分配到的端口号。

Modbus TCP数据帧结构如下

 报文头(MBAP头) 

内容解释
事务处理标识可以理解为报文序列号,一般每次通信后就要加1,以区分不同的通信数据报文。
协议标识符00 00 表示Modbus TCP 协议
长度接下来数据长度,单位字节
单元标识符设备地址,一般为01

 

4.2 ModbusTCP 通讯示例

4.2.1 读输出寄存器:【功能码03】

  • 发送报文格式
事务元处理标识符(高位)事务元处理标识符(低位)协议标识符 高位协议标识符 低位长度  高位长度低位单元标识符功能码起始地址高位起始位 低位寄存器数量 高位寄存器数量 低位
0x150x010x000x000x000x060xFF0x030x000x06B0x000x02

简化版: 

事务/协议长度单元标识功能码起始高起始低数量高数量低
0x150100000x00060xFF0x030x000x6B0x000x02

发送报文含义:读取服务器1号从站输出寄存器,起始地址为0x6B=107(相对地址),对应地址为40108,寄存器数量为0x02=2,即读取1号从站输出寄存器,地址从40108-40109,共两个寄存器的数值。

  • 返回报文格式
事务元处理标识符(高位)事务元处理标识符(低位)协议标识符 高位协议标识符 低位长度  高位长度低位单元标识符功能码字节计数字节一  高位字节一 低位字节二 高位字节二 低位
0x150x010x000x000x000x070xFF0x030x040x020x2B0x010x06

简化版: 

事务/协议长度单元标识功能码字节计数1高1低2高2低
0x150100000x00070x010x030x040x020x2B0x010x06

返回报文含义:返回服务器1号从站输出寄存器40108-40109,共2个寄存器的数值,返回字节数为4个,分别为02、2B、01、06,40108对应数值为0x022B,40109对应数值为0x0106

五、 通信状况

5.1 通信状况

当主机向设备发送命令后,可能会出现以4下种情况:

  • 请求正确的到达服务器,并且请求的内容服务器可以处理,那么服务器返回一个正常响应
  • 请求正确的到达服务器,但是请求服务器无法处理(例如请求读一个不存在的寄存器),此时服务器将返回一个异常响应,通知主机错误和错误的类型。
  • 请求到达服务器,但是不正确,检测到了通信错误(奇偶校验、LRC、CRC等等),那么不返回响应,主机将最终成为超时状态
  • 请求就没到达服务器,服务器没收到也就更不会响应,主机也会成为超时状态

5.2 响应类型

综上,根据服务器处理结果,可以建立两种类型的响应:

一个正常MODBUS应答帧:

  • 功能码域:响应功能码 = 请求功能码
  • 数据域:请求中要求的任何数据
  • 校验码:响应帧自身计算
从站地址功能码数据校验码(低位)校验码(高位)
从站自身地址与请求功能码保持一致(范围:0x00-0x7f)请求中要求的任何数据XXXX

一个异常MODBUS应答帧

  • 用来为客户机提供处理过程中与被发现的差错相关的信息

  • 功能码域:响应功能码 = 请求功能码 + 0x80

  • 数据域:提供一个异常码来指示差错原因

  • 校验码:响应帧自身计算

从站地址功能码数据校验码(低位)校验码(高位)
从站自身地址请求功能码 + 0x80异常码XXXX

 5.3 异常码表

代码名称含义
1非法功能

对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作。

这也许是因为功能码仅仅适用于新设备而在被选单元中是不可实现的。

同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:因为它是未配置的,并且要求返回寄存器值。

2非法数据地址

对于服务器(或从站)来说,询问中接收到的数据地址是不可允许的地址。特别是,参考号和传输长度的组合是无效的。

对于带有 100 个寄存器的控制器来说,带有偏移量 96 和长度 4 的请求会成功,带有偏移量 96 和长度 5 的请求将产生异常码 02。

3非法数据值

对于服务器(或从站)来说,询问中包括的值是不可允许的值。这个值指示了组合请求剩余结构中的故障,

例如:隐含长度是不正确的。

并不意味着,因为MODBUS 协议不知道任何特殊寄存器的任何特殊值的重要意义,

寄存器中被提交存储的数据项有一个应用程序期望之外的值。

4从站设备故障当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。
5确认

与编程命令一起使用。服务器(或从站)已经接受请求,并且正在处理这个请求,但是需要长的持续时间进行这些操作。

返回这个响应防止在客户机(或主站)中发生超时错误。客户机(或主站)可以继续发送轮询程序完成报文来确定是否完成处理。

6从属设备忙与编程命令一起使用。服务器(或从站)正在处理长持续时间的程序命令。当服务器(或从站)空闲时,用户(或主站)应该稍后重新传输报文。
0A不可用网关路径与网关一起使用,指示网关不能为处理请求分配输入端口至输出端口的内部通信路径。通常意味着网关是错误配置的或过载的。
0B网关目标设备响应失败与网关一起使用,指示没有从目标设备中获得响应。通常意味着设备未在网络中。

这篇关于ModbusTcp和ModbusRtu全面理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/751809

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

分布式系统的个人理解小结

分布式系统:分的微小服务,以小而独立的业务为单位,形成子系统。 然后分布式系统中需要有统一的调用,形成大的聚合服务。 同时,微服务群,需要有交流(通讯,注册中心,同步,异步),有管理(监控,调度)。 对外服务,需要有控制的对外开发,安全网关。

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

理解java虚拟机内存收集

学习《深入理解Java虚拟机》时个人的理解笔记 1、为什么要去了解垃圾收集和内存回收技术? 当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些“自动化”的技术实施必要的监控和调节。 2、“哲学三问”内存收集 what?when?how? 那些内存需要回收?什么时候回收?如何回收? 这是一个整体的问题,确定了什么状态的内存可以