build: 10.11.27

refactor: 更新依赖
This commit is contained in:
2248356998 qq.com
2025-09-06 23:34:32 +08:00
parent 662aa162e9
commit 8404e20c5e
20 changed files with 371 additions and 33 deletions

View File

@@ -24,13 +24,13 @@
<ItemGroup>
<PackageReference Include="SqlSugarCore.Dm" Version="8.8.2" />
<PackageReference Include="SqlSugarCore.Kdbndp" Version="9.3.7.821" />
<PackageReference Include="SqlSugarCore.Kdbndp" Version="9.3.7.905" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.20" />
<!--<PackageReference Include="Microsoft.Data.Sqlite" Version="$(NET9Version)" />-->
<PackageReference Include="MySqlConnector" Version="2.4.0" />
<PackageReference Include="Npgsql" Version="9.0.3" />
<PackageReference Include="CsvHelper" Version="33.1.0" />
<PackageReference Include="TDengine.Connector" Version="3.1.8" />
<PackageReference Include="TDengine.Connector" Version="3.1.9" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.9.1" />
<PackageReference Include="Oscar.Data.SqlClient" Version="4.2.23" />
<PackageReference Include="System.Data.Common" Version="4.3.0" />

View File

@@ -1,9 +1,9 @@
<Project>
<PropertyGroup>
<PluginVersion>10.11.26</PluginVersion>
<ProPluginVersion>10.11.26</ProPluginVersion>
<DefaultVersion>10.11.26</DefaultVersion>
<PluginVersion>10.11.27</PluginVersion>
<ProPluginVersion>10.11.27</ProPluginVersion>
<DefaultVersion>10.11.27</DefaultVersion>
<AuthenticationVersion>10.11.3</AuthenticationVersion>
<SourceGeneratorVersion>10.11.3</SourceGeneratorVersion>
<NET8Version>8.0.19</NET8Version>

View File

@@ -49,12 +49,11 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
this.ThrowIfDisposed();
this.ThrowIfClientNotConnected();
if (!await this.OnTcpSending(memory).ConfigureAwait(false)) return;
var transport = this.Transport;
var adapter = this.DataHandlingAdapter;
var locker = transport.SemaphoreSlimForWriter;
var locker = transport.WriteLocker;
await locker.WaitAsync(token).ConfigureAwait(false);
try
@@ -62,7 +61,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
// 如果数据处理适配器未设置,则使用默认发送方式。
if (adapter == null)
{
await transport.Output.WriteAsync(memory, token).ConfigureAwait(false);
await transport.Writer.WriteAsync(memory, token).ConfigureAwait(false);
}
else
{
@@ -70,7 +69,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
var ddpSend = new DDPSend(memory, Id, true);
ddpSend.Build(ref byteBlock);
var newMemory = byteBlock.Memory;
var writer = new PipeBytesWriter(transport.Output);
var writer = new PipeBytesWriter(transport.Writer);
adapter.SendInput(ref writer, in newMemory);
await writer.FlushAsync(token).ConfigureAwait(false);
}
@@ -100,7 +99,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
var transport = this.Transport;
var adapter = this.DataHandlingAdapter;
var locker = transport.SemaphoreSlimForWriter;
var locker = transport.WriteLocker;
await locker.WaitAsync(token).ConfigureAwait(false);
try
@@ -113,7 +112,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
requestInfoBuilder.Build(ref byteBlock);
var ddpSend = new DDPSend(byteBlock.Memory, Id, true);
var writer = new PipeBytesWriter(transport.Output);
var writer = new PipeBytesWriter(transport.Writer);
adapter.SendInput(ref writer, ddpSend);
await writer.FlushAsync(token).ConfigureAwait(false);
}

View File

@@ -34,7 +34,26 @@ public static class PluginUtil
if (channelOptions.ChannelType == ChannelTypeEnum.TcpClient)
{
action += a => a.UseReconnection<IClientChannel>();
action += a => a.UseReconnection<IClientChannel>().SetActionForCheck((channel, failCount) =>
{
if (channel.Online)
{
return Task.FromResult(ConnectionCheckResult.Alive);
}
else
{
if (failCount > 3)
{
return Task.FromResult(ConnectionCheckResult.Dead);
}
return Task.FromResult(ConnectionCheckResult.Skip);
}
})
.SetPollingTick(TimeSpan.FromSeconds(5)
);
}
return action;
}

View File

@@ -11,8 +11,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="$(NET9Version)" />
<PackageReference Include="TouchSocket" Version="4.0.0-beta.13" />
<PackageReference Include="TouchSocket.SerialPorts" Version="4.0.0-beta.13" />
<PackageReference Include="TouchSocket" Version="4.0.0-beta.20" />
<PackageReference Include="TouchSocket.SerialPorts" Version="4.0.0-beta.20" />
</ItemGroup>
<ItemGroup>

View File

@@ -214,6 +214,17 @@ public class ControlController : ControllerBase, IRpcServer
return GlobalData.VariableRuntimeService.InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart);
}
/// <summary>
/// 增加测试Dtu数据
/// </summary>
[HttpPost("insertTestDtuData")]
[DisplayName("增加测试Dtu数据")]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart = true)
{
return GlobalData.VariableRuntimeService.InsertTestDtuDataAsync(testDeviceCount, slaveUrl, restart);
}
/// <summary>
/// 确认实时报警
/// </summary>

View File

@@ -338,6 +338,14 @@ public partial class ManagementController : ControllerBase, IRpcServer
public Task InsertTestDataAsync([FromBody] InsertTestDataInput input) =>
App.GetService<IVariablePageService>().InsertTestDataAsync(input.TestVariableCount, input.TestDeviceCount, input.SlaveUrl, input.BusinessEnable, input.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task InsertTestDtuDataAsync([FromBody] InsertTestDtuDataInput input) =>
App.GetService<IVariablePageService>().InsertTestDtuDataAsync(input.TestDeviceCount, input.SlaveUrl, input.Restart);
[HttpPost]
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
public Task<bool> IsRedundantDeviceAsync(long id) =>
@@ -628,7 +636,12 @@ public class InsertTestDataInput
public bool BusinessEnable { get; set; }
public bool Restart { get; set; }
}
public class InsertTestDtuDataInput
{
public int TestDeviceCount { get; set; }
public string SlaveUrl { get; set; }
public bool Restart { get; set; }
}
public class LastLogDataInput
{
public string File { get; set; }

View File

@@ -221,7 +221,8 @@ public interface IManagementRpcServer : IRpcServer
[DmtpRpc]
Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart);
[DmtpRpc]
Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart);
[DmtpRpc]
Task<bool> IsRedundantDeviceAsync(long id);

View File

@@ -179,6 +179,10 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
public Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart) =>
App.GetService<IVariablePageService>().InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart);
public Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart) =>
App.GetService<IVariablePageService>().InsertTestDtuDataAsync(testDeviceCount, slaveUrl, restart);
public Task<bool> IsRedundantDeviceAsync(long id) =>
App.GetService<IDevicePageService>().IsRedundantDeviceAsync(id);

View File

@@ -134,7 +134,7 @@ public partial class ManagementTask : AsyncDisposableObject
.SetTick(TimeSpan.FromMilliseconds(_managementOptions.HeartbeatInterval))
.SetMaxFailCount(3);
a.AddDmtpHandshakedPlugin(async () =>
a.AddDmtpCreatedChannelPlugin(async () =>
{
try
{

View File

@@ -35,5 +35,6 @@ namespace ThingsGateway.Gateway.Application
Task<OperResult<object>> OnWriteVariableAsync(long id, string writeData);
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableAsync(IBrowserFile a, bool restart);
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableFileAsync(string filePath, bool restart);
Task InsertTestDtuDataAsync(int deviceCount, string slaveUrl, bool restart);
}
}

View File

@@ -111,4 +111,5 @@ internal interface IVariableService
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string filePath);
Task<HashSet<long>> ImportVariableAsync(List<Variable> upData, List<Variable> insertData);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile);
Task<(List<Channel>, List<Device>, List<Variable>)> InsertTestDtuDataAsync(int deviceCount, string slaveUrl = "127.0.0.1:502");
}

View File

@@ -423,6 +423,45 @@ public class VariableRuntimeService : IVariableRuntimeService
}
}
public async Task InsertTestDtuDataAsync(int deviceCount, string slaveUrl, bool restart)
{
try
{
// await WaitLock.WaitAsync().ConfigureAwait(false);
var datas = await GlobalData.VariableService.InsertTestDtuDataAsync(deviceCount, slaveUrl).ConfigureAwait(false);
{
var newChannelRuntimes = datas.Item1.AdaptListChannelRuntime();
//批量修改之后,需要重新加载通道
RuntimeServiceHelper.Init(newChannelRuntimes);
{
var newDeviceRuntimes = datas.Item2.AdaptListDeviceRuntime();
RuntimeServiceHelper.Init(newDeviceRuntimes);
}
{
var newVariableRuntimes = datas.Item3.AdaptListVariableRuntime();
RuntimeServiceHelper.Init(newVariableRuntimes);
}
//根据条件重启通道线程
if (restart)
{
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
}
}
}
finally
{
//WaitLock.Release();
}
}
public Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
{
return GlobalData.VariableService.PreviewAsync(browserFile);

View File

@@ -235,6 +235,144 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
return (newChannels, newDevices, newVariables);
}
public async Task<(List<Channel>, List<Device>, List<Variable>)> InsertTestDtuDataAsync(int deviceCount, string slaveUrl = "127.0.0.1:502")
{
if (slaveUrl.IsNullOrWhiteSpace()) slaveUrl = "127.0.0.1:502";
List<Channel> newChannels = new();
List<Device> newDevices = new();
List<Variable> newVariables = new();
ManageHelper.CheckChannelCount(deviceCount);
ManageHelper.CheckDeviceCount(deviceCount);
ManageHelper.CheckVariableCount(deviceCount);
//DTU
for (int i = 0; i < deviceCount; i++)
{
Channel serviceChannel = new Channel();
Device serviceDevice = new Device();
{
var id = CommonUtils.GetSingleId();
var name = $"modbusSlaveChannel{id}";
serviceChannel.ChannelType = ChannelTypeEnum.TcpClient;
serviceChannel.Name = name;
serviceChannel.Enable = true;
serviceChannel.Id = id;
serviceChannel.CreateUserId = UserManager.UserId;
serviceChannel.CreateOrgId = UserManager.OrgId;
serviceChannel.RemoteUrl = "127.0.0.1:502";
serviceChannel.DtuId = name;
serviceChannel.Heartbeat = "ThingsGateway.Plugin.Modbus";
serviceChannel.PluginName = "ThingsGateway.Plugin.Modbus.ModbusSlave";
newChannels.Add(serviceChannel);
}
{
var id = CommonUtils.GetSingleId();
var name = $"modbusSlaveDevice{id}";
serviceDevice.Name = name;
serviceDevice.Id = id;
serviceDevice.CreateUserId = UserManager.UserId;
serviceDevice.CreateOrgId = UserManager.OrgId;
serviceDevice.ChannelId = serviceChannel.Id;
serviceDevice.IntervalTime = "1000";
newDevices.Add(serviceDevice);
}
}
//SERVICE
var dtuids = newChannels.Select(a => a.Name).ToList();
Channel channel = new Channel();
{
var id = CommonUtils.GetSingleId();
var name = $"modbusChannel{id}";
channel.ChannelType = ChannelTypeEnum.TcpService;
channel.Name = name;
channel.Id = id;
channel.CreateUserId = UserManager.UserId;
channel.CreateOrgId = UserManager.OrgId;
channel.BindUrl = slaveUrl;
channel.Heartbeat = "ThingsGateway.Plugin.Modbus";
channel.PluginName = "ThingsGateway.Plugin.Modbus.ModbusMaster";
//动态插件属性默认
newChannels.Add(channel);
}
foreach (var item in dtuids)
{
Device device = new Device();
{
var id = CommonUtils.GetSingleId();
var name = $"modbusDevice{id}";
device.Name = name;
device.Id = id;
device.ChannelId = channel.Id;
device.CreateUserId = UserManager.UserId;
device.CreateOrgId = UserManager.OrgId;
device.IntervalTime = "1000";
device.DevicePropertys = new Dictionary<string, string>()
{
{
nameof(CollectFoundationDtuPackPropertyBase.DtuId),item
}
};
//动态插件属性默认
newDevices.Add(device);
}
{
var address = $"400001";
var id = CommonUtils.GetSingleId();
var name = $"modbus{address}";
Variable variable = new Variable();
variable.DataType = DataTypeEnum.Int16;
variable.Name = name;
variable.Id = id;
variable.CreateOrgId = UserManager.OrgId;
variable.CreateUserId = UserManager.UserId;
variable.DeviceId = device.Id;
variable.RegisterAddress = address;
newVariables.Add(variable);
}
}
using var db = GetDB();
var result = await db.UseTranAsync(async () =>
{
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory < 2 * 1024 * 1024 || WebEnableVariable.WebEnable == false)
{
await db.BulkCopyAsync(newChannels, 10000).ConfigureAwait(false);
await db.BulkCopyAsync(newDevices, 10000).ConfigureAwait(false);
await db.BulkCopyAsync(newVariables, 10000).ConfigureAwait(false);
}
else
{
await db.BulkCopyAsync(newChannels, 200000).ConfigureAwait(false);
await db.BulkCopyAsync(newDevices, 200000).ConfigureAwait(false);
await db.BulkCopyAsync(newVariables, 200000).ConfigureAwait(false);
}
}).ConfigureAwait(false);
if (result.IsSuccess)//如果成功了
{
}
else
{
throw new(result.ErrorMessage, result.ErrorException);
}
return (newChannels, newDevices, newVariables);
}
#endregion
/// <summary>

View File

@@ -11,9 +11,9 @@
<PackageReference Include="Riok.Mapperly" Version="4.2.1" ExcludeAssets="runtime" PrivateAssets="all" />
<PackageReference Include="Rougamo.Fody" Version="5.0.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.3" />
<PackageReference Include="TouchSocket.Dmtp" Version="4.0.0-beta.13" />
<!--<PackageReference Include="TouchSocket.WebApi.Swagger" Version="4.0.0-beta.13" />-->
<PackageReference Include="TouchSocket.WebApi" Version="4.0.0-beta.13" />
<PackageReference Include="TouchSocket.Dmtp" Version="4.0.0-beta.20" />
<!--<PackageReference Include="TouchSocket.WebApi.Swagger" Version="4.0.0-beta.20" />-->
<PackageReference Include="TouchSocket.WebApi" Version="4.0.0-beta.20" />
<PackageReference Include="ThingsGateway.Authentication" Version="$(AuthenticationVersion)" />
<!--<ProjectReference Include="..\..\PluginPro\ThingsGateway.Authentication\ThingsGateway.Authentication.csproj" />-->

View File

@@ -243,6 +243,7 @@
"BusinessEnable": "BusinessEnable",
"SlaveUrl": "SlaveUrl",
"Test": "Addition of test variables",
"TestDtu": "Addition of test dtu variables",
"TestDeviceCount": "TestDeviceCount",
"TestVariableCount": "TestVariableCount",
"WriteValue": "WriteValue",

View File

@@ -243,6 +243,7 @@
"BusinessEnable": "添加业务设备",
"SlaveUrl": "服务端Url",
"Test": "一键添加测试变量",
"TestDtu": "一键添加Dtu测试变量",
"TestDeviceCount": "采集设备数量",
"TestVariableCount": "变量数量",
"WriteValue": "写入值",

View File

@@ -127,7 +127,7 @@
@if (WebsiteOption.Value.Demo || App.HostEnvironment.IsDevelopment())
{
<PopConfirmButton Color=Color.Warning Text="@Localizer["Test"]" IsKeepDisabled=@(!AuthorizeButton(AdminOperConst.Add))
IsAsync OnConfirm=@(InsertTestDataAsync)>
IsAsync OnConfirm=@(InsertTestDataAsync) class="me-1">
<BodyTemplate>
<BootstrapInput @bind-Value=TestVariableCount ShowLabel="true" ShowLabelTooltip="true" />
@@ -136,6 +136,16 @@
</BodyTemplate>
</PopConfirmButton>
<PopConfirmButton Color=Color.Warning Text="@Localizer["TestDtu"]" IsKeepDisabled=@(!AuthorizeButton(AdminOperConst.Add))
IsAsync OnConfirm=@(InsertTestDtuDataAsync)>
<BodyTemplate>
<BootstrapInput @bind-Value=TestDeviceCount ShowLabel="true" ShowLabelTooltip="true" />
</BodyTemplate>
</PopConfirmButton>
}
</TableToolbarTemplate>

View File

@@ -481,6 +481,32 @@ finally
}
}
private async Task InsertTestDtuDataAsync()
{
try
{
try
{
await Task.Run(() => VariablePageService.InsertTestDtuDataAsync(TestDeviceCount, SlaveUrl, AutoRestartThread));
}
finally
{
await InvokeAsync(async () =>
{
await ToastService.Default();
await table.QueryAsync();
StateHasChanged();
});
}
}
catch (Exception ex)
{
await InvokeAsync(async () => await ToastService.Warn(ex));
}
}
[Parameter]
public bool AutoRestartThread { get; set; }

View File

@@ -10,6 +10,7 @@
using System.Buffers;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using TouchSocket.Sockets;
@@ -184,10 +185,28 @@ public class ModbusSlave : DeviceBase, IModbusAddress
/// <inheritdoc/>
private void Init(ModbusRequest mAddress)
{
//自动扩容
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a =>
{
var bytes = new ByteBlock(ushort.MaxValue * 2);
bytes.SetLength(ushort.MaxValue * 2);
var bytes = new ByteBlock(256,
(c) =>
{
var data= ArrayPool<byte>.Shared.Rent(c);
for (int i = 0; i < data.Length; i++)
{
data[i] = 0;
}
return data;
},
(m) =>
{
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
{
ArrayPool<byte>.Shared.Return(result.Array);
}
}
);
bytes.SetLength(256);
for (int i = 0; i < bytes.Length; i++)
{
bytes.WriteByte(0);
@@ -197,8 +216,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
});
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a =>
{
var bytes = new ByteBlock(ushort.MaxValue * 2);
bytes.SetLength(ushort.MaxValue * 2);
var bytes = new ByteBlock(256,
(c) =>
{
var data = ArrayPool<byte>.Shared.Rent(c);
for (int i = 0; i < data.Length; i++)
{
data[i] = 0;
}
return data;
},
(m) =>
{
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
{
ArrayPool<byte>.Shared.Return(result.Array);
}
}
);
bytes.SetLength(256);
for (int i = 0; i < bytes.Length; i++)
{
bytes.WriteByte(0);
@@ -208,8 +244,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
});
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a =>
{
var bytes = new ByteBlock(ushort.MaxValue * 2);
bytes.SetLength(ushort.MaxValue * 2);
var bytes = new ByteBlock(256,
(c) =>
{
var data = ArrayPool<byte>.Shared.Rent(c);
for (int i = 0; i < data.Length; i++)
{
data[i] = 0;
}
return data;
},
(m) =>
{
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
{
ArrayPool<byte>.Shared.Return(result.Array);
}
}
);
bytes.SetLength(256);
for (int i = 0; i < bytes.Length; i++)
{
bytes.WriteByte(0);
@@ -219,8 +272,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
});
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a =>
{
var bytes = new ByteBlock(ushort.MaxValue * 2);
bytes.SetLength(ushort.MaxValue * 2);
var bytes = new ByteBlock(256,
(c) =>
{
var data = ArrayPool<byte>.Shared.Rent(c);
for (int i = 0; i < data.Length; i++)
{
data[i] = 0;
}
return data;
},
(m) =>
{
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
{
ArrayPool<byte>.Shared.Return(result.Array);
}
}
);
bytes.SetLength(256);
for (int i = 0; i < bytes.Length; i++)
{
bytes.WriteByte(0);
@@ -278,16 +348,20 @@ public class ModbusSlave : DeviceBase, IModbusAddress
switch (f)
{
case 1:
return OperResult.CreateSuccessResult(ModbusServer01ByteBlock.Memory.Slice(mAddress.StartAddress, len));
ModbusServer01ByteBlock.Position = mAddress.StartAddress;
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer01ByteBlock.GetMemory(len).Slice(0, len));
case 2:
return OperResult.CreateSuccessResult(ModbusServer02ByteBlock.Memory.Slice(mAddress.StartAddress, len));
ModbusServer02ByteBlock.Position = mAddress.StartAddress;
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer02ByteBlock.GetMemory(len).Slice(0, len));
case 3:
return OperResult.CreateSuccessResult(ModbusServer03ByteBlock.Memory.Slice(mAddress.StartAddress * RegisterByteLength, len));
ModbusServer03ByteBlock.Position = mAddress.StartAddress * RegisterByteLength;
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer03ByteBlock.GetMemory(len).Slice(0, len));
case 4:
return OperResult.CreateSuccessResult(ModbusServer04ByteBlock.Memory.Slice(mAddress.StartAddress * RegisterByteLength, len));
ModbusServer04ByteBlock.Position = mAddress.StartAddress * RegisterByteLength;
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer04ByteBlock.GetMemory(len).Slice(0, len));
}
}
}