diff --git a/examples/Modbus/ModbusObjectConsoleApp/Program.cs b/examples/Modbus/ModbusObjectConsoleApp/Program.cs index dadca6815..6b31c7229 100644 --- a/examples/Modbus/ModbusObjectConsoleApp/Program.cs +++ b/examples/Modbus/ModbusObjectConsoleApp/Program.cs @@ -27,7 +27,7 @@ namespace ModbusObjectConsoleApp myModbusObject.MyProperty11 = new bool[] { false, true, false, true, false, true, false, true, false };//直接赋值多线圈 myModbusObject.MyProperty3 = 1;//直接赋值保持寄存器 - myModbusObject.MyProperty33 = new short[] {1,2,3,4,5,6,7,8,9 };//直接赋值保持寄存器 + myModbusObject.MyProperty33 = new short[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };//直接赋值保持寄存器 Console.WriteLine(myModbusObject.MyProperty1.ToJsonString()); Console.WriteLine(myModbusObject.MyProperty11.ToJsonString()); @@ -51,7 +51,13 @@ namespace ModbusObjectConsoleApp //监听端口 .SetListenIPHosts(7808) //设置数据存储区,即线圈、离散输入、保持寄存器、输入寄存器 - .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10)) + .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10) + { + Coils = new DataPartition(1000, new bool[10]), + DiscreteInputs = new DataPartition(1000, new bool[10]), + HoldingRegisters = new DataPartition(1000, new byte[20]), + InputRegisters = new DataPartition(1000, new byte[20]) + }) ); service.Start(); Console.WriteLine("服务已启动"); @@ -80,7 +86,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.Coils, StartAddress = 0, Timeout = 1000)] + [ModbusProperty(SlaveId = 1, Partition = Partition.Coils, StartAddress = 1000, Timeout = 1000)] public bool MyProperty1 { get { return this.GetValue(); } @@ -93,7 +99,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间、数量 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.Coils, StartAddress = 1, Timeout = 1000, Quantity = 9)] + [ModbusProperty(SlaveId = 1, Partition = Partition.Coils, StartAddress = 1001, Timeout = 1000, Quantity = 9)] public bool[] MyProperty11 { get { return this.GetValueArray(); } @@ -108,7 +114,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.DiscreteInputs, StartAddress = 0, Timeout = 1000)] + [ModbusProperty(SlaveId = 1, Partition = Partition.DiscreteInputs, StartAddress = 1000, Timeout = 1000)] public bool MyProperty2 { get { return this.GetValue(); } @@ -120,7 +126,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间、数量 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.DiscreteInputs, StartAddress = 1, Timeout = 1000, Quantity = 9)] + [ModbusProperty(SlaveId = 1, Partition = Partition.DiscreteInputs, StartAddress = 1001, Timeout = 1000, Quantity = 9)] public bool MyProperty22 { get { return this.GetValue(); } @@ -134,7 +140,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间、端序 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.HoldingRegisters, StartAddress = 0, Timeout = 1000, EndianType = TouchSocket.Core.EndianType.Big)] + [ModbusProperty(SlaveId = 1, Partition = Partition.HoldingRegisters, StartAddress = 1000, Timeout = 1000, EndianType = EndianType.Big)] public short MyProperty3 { get { return this.GetValue(); } @@ -147,7 +153,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间、端序、数组长度 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.HoldingRegisters, StartAddress = 1, Timeout = 1000, EndianType = TouchSocket.Core.EndianType.Big, Quantity = 9)] + [ModbusProperty(SlaveId = 1, Partition = Partition.HoldingRegisters, StartAddress = 1001, Timeout = 1000, EndianType = TouchSocket.Core.EndianType.Big, Quantity = 9)] public short[] MyProperty33 { get { return this.GetValueArray(); } @@ -162,7 +168,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间、端序 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.InputRegisters, StartAddress = 0, Timeout = 1000, EndianType = TouchSocket.Core.EndianType.Big)] + [ModbusProperty(SlaveId = 1, Partition = Partition.InputRegisters, StartAddress = 1000, Timeout = 1000, EndianType = EndianType.Big)] public short MyProperty4 { get { return this.GetValue(); } @@ -174,7 +180,7 @@ namespace ModbusObjectConsoleApp /// 配置:站号、数据区、起始地址、超时时间、端序、数组长度 /// /// - [ModbusProperty(SlaveId = 1, Partition = Partition.InputRegisters, StartAddress = 0, Timeout = 1000, EndianType = TouchSocket.Core.EndianType.Big, Quantity = 10)] + [ModbusProperty(SlaveId = 1, Partition = Partition.InputRegisters, StartAddress = 1000, Timeout = 1000, EndianType = EndianType.Big, Quantity = 10)] public short[] MyProperty44 { get { return this.GetValueArray(); } diff --git a/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Controllers/WeatherForecastController.cs b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Controllers/WeatherForecastController.cs new file mode 100644 index 000000000..9efd07bda --- /dev/null +++ b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace WebApplication_NET6.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Program.cs b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Program.cs new file mode 100644 index 000000000..cfb9e9145 --- /dev/null +++ b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Program.cs @@ -0,0 +1,35 @@ +namespace WebApplication_NET6 +{ + public class Program + { + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseAuthorization(); + + + app.MapControllers(); + + app.Run(); + } + } +} diff --git a/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Properties/launchSettings.json b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Properties/launchSettings.json new file mode 100644 index 000000000..54d93561c --- /dev/null +++ b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:26141", + "sslPort": 0 + } + }, + "profiles": { + "WebApplication_NET6": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5270", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/WebApplication_NET6.csproj b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/WebApplication_NET6.csproj new file mode 100644 index 000000000..34eb3ce6f --- /dev/null +++ b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/WebApplication_NET6.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/appsettings.Development.json b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/appsettings.json b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/appsettings.json new file mode 100644 index 000000000..10f68b8c8 --- /dev/null +++ b/examples_host/Examples.Host/Aspnetcore/WebApplication_NET6/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/examples_host/Examples.Host/Examples.Host.sln b/examples_host/Examples.Host/Examples.Host.sln new file mode 100644 index 000000000..f4ca77514 --- /dev/null +++ b/examples_host/Examples.Host/Examples.Host.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34322.80 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aspnetcore", "Aspnetcore", "{317E3933-5817-49B4-9C2B-067DA6D051EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication_NET6", "Aspnetcore\WebApplication_NET6\WebApplication_NET6.csproj", "{9F419CC4-F34E-4B6C-B2B8-F86FE7A4DE52}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9F419CC4-F34E-4B6C-B2B8-F86FE7A4DE52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9F419CC4-F34E-4B6C-B2B8-F86FE7A4DE52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9F419CC4-F34E-4B6C-B2B8-F86FE7A4DE52}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9F419CC4-F34E-4B6C-B2B8-F86FE7A4DE52}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {9F419CC4-F34E-4B6C-B2B8-F86FE7A4DE52} = {317E3933-5817-49B4-9C2B-067DA6D051EF} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {04D833EF-6EB7-4BAA-A5F0-1C587472EA86} + EndGlobalSection +EndGlobal diff --git a/handbook/docs/description.mdx b/handbook/docs/description.mdx index e2a8523bc..ccd2ec17c 100644 --- a/handbook/docs/description.mdx +++ b/handbook/docs/description.mdx @@ -44,6 +44,13 @@ TouchSocket 由作者若汝棋茗及其他贡献者开发,所有版权归作 - [![NuGet version (TouchSocket.WebApi.Swagger)](https://img.shields.io/nuget/v/TouchSocket.WebApi.Swagger.svg?label=TouchSocket.WebApi.Swagger)](https://www.nuget.org/packages/TouchSocket.WebApi.Swagger) - [![NuGet version (TouchSocket.Hosting)](https://img.shields.io/nuget/v/TouchSocket.Hosting.svg?label=TouchSocket.Hosting)](https://www.nuget.org/packages/TouchSocket.Hosting) - [![NuGet version (TouchSocket.AspNetCore)](https://img.shields.io/nuget/v/TouchSocket.AspNetCore.svg?label=TouchSocket.AspNetCore)](https://www.nuget.org/packages/TouchSocket.AspNetCore) +- [![NuGet version (TouchSocket.Modbus)](https://img.shields.io/nuget/v/TouchSocket.Modbus.svg?label=TouchSocket.Modbus)](https://www.nuget.org/packages/TouchSocket.Modbus) + +:::tip 提示 + +即所有以“TouchSocket”开头的Nuget包,均已完全开源,个人、商用均可完全免费使用。 + +::: # Apache License 2.0 开源协议简述 @@ -115,6 +122,13 @@ TouchSocket核心部分都是开源免费的,所以我们希望当它帮到您 - [![NuGet version (TouchSocketPro)](https://img.shields.io/nuget/v/TouchSocketPro.svg?label=TouchSocketPro)](https://www.nuget.org/packages/TouchSocketPro) - [![NuGet version (TouchSocketPro.Dmtp)](https://img.shields.io/nuget/v/TouchSocketPro.Dmtp.svg?label=TouchSocketPro.Dmtp)](https://www.nuget.org/packages/TouchSocketPro.Dmtp) - [![NuGet version (TouchSocketPro.AspNetCore)](https://img.shields.io/nuget/v/TouchSocketPro.AspNetCore.svg?label=TouchSocketPro.AspNetCore)](https://www.nuget.org/packages/TouchSocketPro.AspNetCore) +- [![NuGet version (TouchSocketPro.Modbus)](https://img.shields.io/nuget/v/TouchSocketPro.Modbus.svg?label=TouchSocketPro.Modbus)](https://www.nuget.org/packages/TouchSocketPro.Modbus) + +:::tip 提示 + +即所有以“TouchSocketPro”开头的Nuget包,这可能需要授权才可以使用。 + +::: ### TouchSocketPro 功能部分遵循: diff --git a/handbook/docs/generichost.mdx b/handbook/docs/generichost.mdx index 3d29f0604..6a1c24fff 100644 --- a/handbook/docs/generichost.mdx +++ b/handbook/docs/generichost.mdx @@ -14,15 +14,26 @@ title: 通用主机 Hosting通用主机,是在创建一个[HostBuilder](https://learn.microsoft.com/zh-cn/dotnet/core/extensions/generic-host) 之后,可以通过Add的服务的形式创建`TouchSocket`的一些组件。如`TcpService`、`TcpClient`、`NamedPipeService`、`NamedPipeclient`等。 -## 二、使用 -### 2.1 安装Nuget包 +## 二、安装Nuget包 -在安装Nuget之前,最好先确认目标项目是一个主机项目。例如:[辅助角色服务模板](https://learn.microsoft.com/zh-cn/dotnet/core/extensions/generic-host)、 [AspNetCore](https://learn.microsoft.com/zh-cn/aspnet/core)等。如果是其他项目,请自行解决。 +在安装Nuget之前,最好先确认目标项目是一个主机项目。例如:[辅助角色服务模板](https://learn.microsoft.com/zh-cn/dotnet/core/extensions/generic-host)、 [AspNetCore](https://learn.microsoft.com/zh-cn/aspnet/core)等。如果是其他项目,请自行解决依赖。 -Nuget安装`TouchSocket.Hosting`。 +使用Nuget安装`TouchSocket.Hosting`、`TouchSocketPro.Hosting`、`TouchSocket.AspNetCore`、`TouchSocketPro.AspNetCore`其中的**任意一个**。 -### 2.2 添加服务 +:::info 备注 + +`TouchSocket.Hosting`、`TouchSocketPro.Hosting`、`TouchSocket.AspNetCore`、`TouchSocketPro.AspNetCore`都可以安装使用。主要区别就是:Hosting的只包含基础扩展。AspNetCore的会对Web项目有更多扩展。 + +::: + +:::tip 建议 + +一般建议Web项目使用`TouchSocket.AspNetCore`、`TouchSocketPro.AspNetCore`。辅助角色项目、MAUI项目等使用`TouchSocket.Hosting`、`TouchSocketPro.Hosting`。 + +::: + +## 三、添加服务 一些常用的组件,都已经被封装了,可以直接使用。例如: @@ -30,6 +41,65 @@ Nuget安装`TouchSocket.Hosting`。 - TcpClient - 等 +### 3.1 在Aspnetcore中添加 + + + + +```cs showLineNumbers {11-13} +using Microsoft.AspNetCore.Mvc; + +namespace Furion.Web.Entry.Controllers +{ + [Route("api/[controller]")] + public class DefaultController : ControllerBase + { + [HttpGet] + public string Get() + { + return $@"名称:{App.Configuration["AppInfo:Name"]}, + 版本:{App.Configuration["AppInfo:Version"]}, + 公司:{App.Configuration["AppInfo:Company"]}"; + } + } +} +``` + + + + +```cs showLineNumbers {2,10-15} +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; + +namespace Furion.Web.Entry.Controllers +{ + [Route("api/[controller]")] + public class DefaultController : ControllerBase + { + [HttpGet] + public string Get([FromServices] IConfiguration configuration) + { + return $@"名称:{configuration["AppInfo:Name"]}, + 版本:{configuration["AppInfo:Version"]}, + 公司:{configuration["AppInfo:Company"]}"; + } + } +} +``` + + + + ```csharp showLineNumbers var builder = Host.CreateDefaultBuilder(args); diff --git a/handbook/docs/modbusslave.mdx b/handbook/docs/modbusslave.mdx index 2a6bd0509..fa6bbef4d 100644 --- a/handbook/docs/modbusslave.mdx +++ b/handbook/docs/modbusslave.mdx @@ -45,16 +45,16 @@ Modbus是主从通讯的。所以我们开发了Modbus服务器组件,方便 ```csharp showLineNumbers static ModbusTcpSlave CreateModbusTcpSlave() { - var service = new ModbusTcpSlave(); - service.Setup(new TouchSocketConfig() + var slave = new ModbusTcpSlave(); + slave.Setup(new TouchSocketConfig() //监听7808端口 .SetListenIPHosts(7808) //设置数据存储区,即线圈、离散输入、保持寄存器、输入寄存器 .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10)) ); - service.Start(); + slave.Start(); Console.WriteLine("服务已启动"); - return service; + return slave; } ``` @@ -63,16 +63,16 @@ static ModbusTcpSlave CreateModbusTcpSlave() ```csharp showLineNumbers static ModbusUdpSlave CreateModbusUdpSlave() { - var service = new ModbusUdpSlave(); - service.Setup(new TouchSocketConfig() + var slave = new ModbusUdpSlave(); + slave.Setup(new TouchSocketConfig() //监听端口 .SetBindIPHost(7809) //设置数据存储区,即线圈、离散输入、保持寄存器、输入寄存器 .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10)) ); - service.Start(); + slave.Start(); Console.WriteLine("服务已启动"); - return service; + return slave; } ``` @@ -81,8 +81,8 @@ static ModbusUdpSlave CreateModbusUdpSlave() ```csharp showLineNumbers static ModbusRtuSlave CreateModbusRtuSlave() { - var service = new ModbusRtuSlave(); - service.Setup(new TouchSocketConfig() + var slave = new ModbusRtuSlave(); + slave.Setup(new TouchSocketConfig() //设置串口 .SetSerialPortOption(new SerialPortOption() { @@ -95,9 +95,9 @@ static ModbusRtuSlave CreateModbusRtuSlave() //设置数据存储区,即线圈、离散输入、保持寄存器、输入寄存器 .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10)) ); - service.Connect(); + slave.Connect(); Console.WriteLine("已连接COM端口"); - return service; + return slave; } ``` @@ -106,16 +106,16 @@ static ModbusRtuSlave CreateModbusRtuSlave() ```csharp showLineNumbers static ModbusRtuOverTcpSlave CreateModbusRtuOverTcpSlave() { - var service = new ModbusRtuOverTcpSlave(); - service.Setup(new TouchSocketConfig() + var slave = new ModbusRtuOverTcpSlave(); + slave.Setup(new TouchSocketConfig() //监听端口 .SetListenIPHosts(7810) //设置数据存储区,即线圈、离散输入、保持寄存器、输入寄存器 .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10)) ); - service.Start(); + slave.Start(); Console.WriteLine("服务已启动"); - return service; + return slave; } ``` @@ -124,16 +124,16 @@ static ModbusRtuOverTcpSlave CreateModbusRtuOverTcpSlave() ```csharp showLineNumbers static ModbusRtuOverUdpSlave CreateModbusRtuOverUdpSlave() { - var service = new ModbusRtuOverUdpSlave(); - service.Setup(new TouchSocketConfig() + var slave = new ModbusRtuOverUdpSlave(); + slave.Setup(new TouchSocketConfig() //监听端口 .SetBindIPHost(7811) //设置数据存储区,即线圈、离散输入、保持寄存器、输入寄存器 .SetModbusDataLocater(new ModbusDataLocater(10, 10, 10, 10)) ); - service.Start(); + slave.Start(); Console.WriteLine("服务已启动"); - return service; + return slave; } ``` @@ -143,16 +143,22 @@ static ModbusRtuOverUdpSlave CreateModbusRtuOverUdpSlave() 该属性是可读可写的。所以,即使是不同`ModbusSlave`。也可以使用同一个存储区。 -同时。可以通过该属性,创建一个本地`ModbusClient`,用于直接读写。 +同时。可以通过该属性,创建一个本地`ModbusMaster`,用于直接读写。 -具体读写操作和[ModbusClient读写](./modbusmaster.mdx)一致。 +具体读写操作和[ModbusMaster读写](./modbusmaster.mdx)一致。 ```csharp showLineNumbers -var client = service.ModbusDataLocater.CreateDataLocaterClient(); +var master = slave.ModbusDataLocater.CreateDataLocaterMaster(); -client.ReadCoils(1,0,1); +master.ReadCoils(1,0,1); ``` +:::tip 提示 + +通过`slave.ModbusDataLocater.CreateDataLocaterMaster()`创建的Master,具备[ModbusMaster](./modbusmaster.mdx)的所有功能。且是直接读取内存的,中间没有任何通信,所以速度非常快。 + +::: + [本文示例Demo](https://gitee.com/RRQM_Home/TouchSocket/tree/master/examples/Modbus/ModbusSlaveConsoleApp)