Commit 5d8bde7a by 何阳

基础功能调通

parent 0d42f339
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DC69BE48-99DE-4533-B15D-FF9109CF1614}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ClientTest</RootNamespace>
<AssemblyName>ClientTest</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="MessagePack, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL">
<HintPath>..\packages\MessagePack.2.5.140\lib\netstandard2.0\MessagePack.dll</HintPath>
</Reference>
<Reference Include="MessagePack.Annotations, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL">
<HintPath>..\packages\MessagePack.Annotations.2.5.140\lib\netstandard2.0\MessagePack.Annotations.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.NET.StringTools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.NET.StringTools.17.6.3\lib\net472\Microsoft.NET.StringTools.dll</HintPath>
</Reference>
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\packages\Serilog.2.10.0\lib\net46\Serilog.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.6.0.0\lib\net461\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ObejctEx.cs" />
<Compile Include="PipeEx.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using MessagePack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
namespace FaceServer
{
public static class ObejctEx
{
public static T ToObejct<T>(this byte[] @this)
{
T data = MessagePackSerializer.Deserialize<T>(@this);
return data;
}
}
}
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MessagePack;
using Serilog;
namespace FaceServer
{
public static class PipeEx
{
public static void Write(this PipeStream @this, byte[] data)
{
@this.Write(BitConverter.GetBytes(data.Length), 0, sizeof(int));
@this.Write(data, 0, data.Length);
}
public static async Task<byte[]> GetBytes(this PipeStream @this)
{
var len = await GetDataLengthAsync(@this);
var data = await GetData(@this, len);
return data;
}
public static async Task WriteAsync(this PipeStream @this, byte[] data)
{
await @this.WriteAsync(BitConverter.GetBytes(data.Length), 0, sizeof(int));
await @this.WriteAsync(data, 0, data.Length);
}
public static async Task<byte[]> ReadBytesAsync(this PipeStream @this)
{
try
{
// 尝试读取下一个数据包的长度
var dataLength = await @this.GetDataLengthAsync();
// 读取数据包
byte[] data = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = await @this.ReadAsync(data, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
return data;
}
catch (IOException ex)
{
Log.Error(ex, "读取管道数据时发生 I/O 异常");
throw;
}
catch (Exception ex)
{
Log.Error(ex, "反序列化 FrameData 时发生异常");
throw;
}
}
public static List<byte[]> ReadAllAvailableFrameData(this PipeStream @this)
{
var allFrameData = new List<byte[]>();
// 如果管道里有数据可以取
try
{
// 尝试读取下一个数据包的长度
var dataLength = @this.GetDataLengthAsync().Result;
// 读取数据包
byte[] data = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = @this.Read(data, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
allFrameData.Add(data);
}
catch (IOException ex)
{
Log.Error(ex, "读取管道数据时发生 I/O 异常");
throw;
}
catch (Exception ex)
{
Log.Error(ex, "反序列化 FrameData 时发生异常");
throw;
}
return allFrameData;
}
public static async Task<int> GetDataLengthAsync(this PipeStream @this)
{
byte[] lengthBuffer = new byte[4];
await @this.ReadAsync(lengthBuffer, 0, 4);
var dataLength = BitConverter.ToInt32(lengthBuffer, 0);
return dataLength;
}
public static async Task<byte[]> GetData(this PipeStream @this, int dataLength)
{
// 然后读取相应长度的数据
byte[] buffer = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = await @this.ReadAsync(buffer, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
return buffer;
}
}
}
using FaceServer;
using MessagePack;
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Reflection.Emit;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
namespace ClientTest
{
[MessagePackObject]
public struct RectangleSerializable
{
[Key(0)]
public int X;
[Key(1)]
public int Y;
[Key(2)]
public int Width;
[Key(3)]
public int Height;
public RectangleSerializable(int x, int y, int w, int h) : this()
{
X = x;
Y = y;
Width = w;
Height = h;
}
public override string ToString()
{
return $"X={X},Y={Y},W={Width},H={Height}";
}
}
[MessagePackObject]
public struct FaceData
{
[Key(0)]
public RectangleSerializable FaceRect;
[Key(1)]
public string Name;
[Key(2)]
public bool IsIdentified;
}
internal class Program
{
private static NamedPipeClientStream PipeClient;
static void Main(string[] args)
{
PipeClient = new NamedPipeClientStream(".", "TEST", PipeDirection.InOut, PipeOptions.Asynchronous, TokenImpersonationLevel.None);
PipeClient.Connect(500);
PipeClient.ReadMode = PipeTransmissionMode.Byte;
while (PipeClient.IsConnected)
{
try
{
var list = PipeClient.GetBytes().Result.ToObejct<List<FaceData>>();
foreach (var test in list)
{
Console.WriteLine("识别到人脸 " + test.Name);
Console.WriteLine("位置 " + test.FaceRect);
Console.WriteLine("值 " + test.IsIdentified);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ClientTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClientTest")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("dc69be48-99de-4533-b15d-ff9109cf1614")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MessagePack" version="2.5.140" targetFramework="net48" />
<package id="MessagePack.Annotations" version="2.5.140" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net48" />
<package id="Microsoft.NET.StringTools" version="17.6.3" targetFramework="net48" />
<package id="Serilog" version="2.10.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Collections.Immutable" version="6.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Reflection.Emit" version="4.7.0" targetFramework="net48" />
<package id="System.Reflection.Emit.Lightweight" version="4.7.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
</packages>
\ No newline at end of file
...@@ -7,20 +7,50 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceApp", "FaceApp\FaceApp. ...@@ -7,20 +7,50 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceApp", "FaceApp\FaceApp.
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceServer", "FaceServer\FaceServer.csproj", "{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceServer", "FaceServer\FaceServer.csproj", "{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerTest", "ServerTest\ServerTest.csproj", "{0A3C84AF-FF06-4770-B00D-F938A1431D42}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientTest", "ClientTest\ClientTest.csproj", "{DC69BE48-99DE-4533-B15D-FF9109CF1614}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{269111C4-EDB6-485D-B47E-C62AE703021C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{269111C4-EDB6-485D-B47E-C62AE703021C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{269111C4-EDB6-485D-B47E-C62AE703021C}.Debug|x64.ActiveCfg = Debug|x64 {269111C4-EDB6-485D-B47E-C62AE703021C}.Debug|x64.ActiveCfg = Debug|x64
{269111C4-EDB6-485D-B47E-C62AE703021C}.Debug|x64.Build.0 = Debug|x64 {269111C4-EDB6-485D-B47E-C62AE703021C}.Debug|x64.Build.0 = Debug|x64
{269111C4-EDB6-485D-B47E-C62AE703021C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{269111C4-EDB6-485D-B47E-C62AE703021C}.Release|Any CPU.Build.0 = Release|Any CPU
{269111C4-EDB6-485D-B47E-C62AE703021C}.Release|x64.ActiveCfg = Release|x64 {269111C4-EDB6-485D-B47E-C62AE703021C}.Release|x64.ActiveCfg = Release|x64
{269111C4-EDB6-485D-B47E-C62AE703021C}.Release|x64.Build.0 = Release|x64 {269111C4-EDB6-485D-B47E-C62AE703021C}.Release|x64.Build.0 = Release|x64
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Debug|x64.ActiveCfg = Debug|x64 {1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Debug|x64.ActiveCfg = Debug|x64
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Debug|x64.Build.0 = Debug|x64 {1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Debug|x64.Build.0 = Debug|x64
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Release|Any CPU.Build.0 = Release|Any CPU
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Release|x64.ActiveCfg = Release|x64 {1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Release|x64.ActiveCfg = Release|x64
{1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Release|x64.Build.0 = Release|x64 {1A20E2DE-F5FD-4555-93CE-AC9CEE9E8FA2}.Release|x64.Build.0 = Release|x64
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Debug|x64.ActiveCfg = Debug|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Debug|x64.Build.0 = Debug|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Release|Any CPU.Build.0 = Release|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Release|x64.ActiveCfg = Release|Any CPU
{0A3C84AF-FF06-4770-B00D-F938A1431D42}.Release|x64.Build.0 = Release|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Debug|x64.Build.0 = Debug|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Release|Any CPU.Build.0 = Release|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Release|x64.ActiveCfg = Release|Any CPU
{DC69BE48-99DE-4533-B15D-FF9109CF1614}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
...@@ -25,6 +25,10 @@ ...@@ -25,6 +25,10 @@
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly> </dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
</configuration> </configuration>
\ No newline at end of file
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<StartupObject>FaceServer.Program</StartupObject> <StartupObject>FaceServer.Program</StartupObject>
...@@ -48,6 +50,7 @@ ...@@ -48,6 +50,7 @@
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion> <LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath> <OutputPath>bin\x64\Release\</OutputPath>
...@@ -58,6 +61,7 @@ ...@@ -58,6 +61,7 @@
<LangVersion>7.3</LangVersion> <LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit> <Prefer32Bit>true</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DlibDotNet, Version=19.21.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DlibDotNet, Version=19.21.0.0, Culture=neutral, processorArchitecture=MSIL">
...@@ -72,6 +76,9 @@ ...@@ -72,6 +76,9 @@
<Reference Include="MessagePack.Annotations, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL"> <Reference Include="MessagePack.Annotations, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL">
<HintPath>..\packages\MessagePack.Annotations.2.5.140\lib\netstandard2.0\MessagePack.Annotations.dll</HintPath> <HintPath>..\packages\MessagePack.Annotations.2.5.140\lib\netstandard2.0\MessagePack.Annotations.dll</HintPath>
</Reference> </Reference>
<Reference Include="MessagePack.ImmutableCollection, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL">
<HintPath>..\packages\MessagePack.ImmutableCollection.2.5.140\lib\netstandard2.0\MessagePack.ImmutableCollection.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference> </Reference>
...@@ -89,6 +96,12 @@ ...@@ -89,6 +96,12 @@
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="protobuf-net, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.3.2.30\lib\net462\protobuf-net.dll</HintPath>
</Reference>
<Reference Include="protobuf-net.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.Core.3.2.30\lib\net462\protobuf-net.Core.dll</HintPath>
</Reference>
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL"> <Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\packages\Serilog.2.10.0\lib\net46\Serilog.dll</HintPath> <HintPath>..\packages\Serilog.2.10.0\lib\net46\Serilog.dll</HintPath>
</Reference> </Reference>
...@@ -105,8 +118,8 @@ ...@@ -105,8 +118,8 @@
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath> <HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Collections.Immutable, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.6.0.0\lib\net461\System.Collections.Immutable.dll</HintPath> <HintPath>..\packages\System.Collections.Immutable.7.0.0\lib\net462\System.Collections.Immutable.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Drawing.Common, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Drawing.Common, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
...@@ -143,6 +156,7 @@ ...@@ -143,6 +156,7 @@
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Util\ConvertEx.cs" />
<Compile Include="Util\FaceRecognitionThread.cs" /> <Compile Include="Util\FaceRecognitionThread.cs" />
<Compile Include="Util\FaceUtil.cs" /> <Compile Include="Util\FaceUtil.cs" />
<Compile Include="Logging.cs" /> <Compile Include="Logging.cs" />
...@@ -203,6 +217,9 @@ ...@@ -203,6 +217,9 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\MessagePackAnalyzer.2.5.140\analyzers\dotnet\MessagePackAnalyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup> <PropertyGroup>
......
using MessagePack; using Microsoft.Win32;
using Microsoft.Win32;
using Serilog; using Serilog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing; using System.Drawing;
using System.IO;
using System.IO.Pipes; using System.IO.Pipes;
using System.Linq; using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
...@@ -124,7 +118,7 @@ namespace FaceServer ...@@ -124,7 +118,7 @@ namespace FaceServer
} }
} }
} }
Queue<byte[]> priorityQueue = new Queue<byte[]>();
private async Task FaceServerAsync() private async Task FaceServerAsync()
{ {
try try
...@@ -133,25 +127,15 @@ namespace FaceServer ...@@ -133,25 +127,15 @@ namespace FaceServer
while (pipeServer.IsConnected) while (pipeServer.IsConnected)
{ {
// 读取所有数据帧,然后直接选取最后一个,其他丢弃 // 读取所有数据帧,然后直接选取最后一个,其他丢弃
var jpegData = pipeServer.ReadAllAvailableFrameData()?.Last(); var jpegData = await pipeServer.ReadBytesAsync();
if (jpegData == null){ if (jpegData == null || jpegData.Length == 0)
{
continue; continue;
} }
// 对jpeg图片做人脸识别 lock (priorityQueue)
var result = Server.Recognition(jpegData);
// 没数据,进下一轮
if (result.Count <= 0)
{ {
continue; priorityQueue.Enqueue(jpegData);
} }
result.ForEach(f => Log.Information($"识别到人脸:{f.Name} 位置:{f.FaceRect}"));
// 序列化要发送的数据
var send = MessagePackSerializer.Serialize(result);
// 发送包头,标记后面数据长度
await pipeServer.WriteAsync(BitConverter.GetBytes(send.Length), 0, 4);
// 发送正式数据
await pipeServer.WriteAsync(send, 0, send.Length);
} }
} }
catch (Exception ex) catch (Exception ex)
...@@ -159,14 +143,6 @@ namespace FaceServer ...@@ -159,14 +143,6 @@ namespace FaceServer
Log.Error(ex, "处理管道数据时发生错误"); Log.Error(ex, "处理管道数据时发生错误");
// 处理异常 // 处理异常
} }
finally
{
// 检查连接状态并断开(如果客户端还未断开)
if (pipeServer.IsConnected)
{
pipeServer.Close();
}
}
} }
...@@ -184,19 +160,69 @@ namespace FaceServer ...@@ -184,19 +160,69 @@ namespace FaceServer
_initCompletionSource.SetResult(true); _initCompletionSource.SetResult(true);
}); });
Task.Factory.StartNew(async () => Task.Factory.StartNew(async () =>
{ {
await _initCompletionSource.Task; await _initCompletionSource.Task;
pipeServer = new NamedPipeServerStream("FACE", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
Log.Information("开始运行命名管道"); Log.Information("开始运行命名管道");
while (true) while (true)
{ {
pipeServer = new NamedPipeServerStream("FACE", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
Log.Information("开始监听");
await pipeServer.WaitForConnectionAsync(); await pipeServer.WaitForConnectionAsync();
Log.Information("客户端已连接"); Log.Information("客户端已连接");
await FaceServerAsync(); await FaceServerAsync();
Log.Information("客户端已断开连接"); Log.Information("客户端已断开连接");
} }
},TaskCreationOptions.LongRunning);
Task.Factory.StartNew(async () =>
{
await _initCompletionSource.Task;
while (true)
{
try
{
byte[] jpegData;
lock (priorityQueue)
{
if (priorityQueue.Count == 0)
{
continue;
}
jpegData = priorityQueue.Last();
priorityQueue.Clear();
}
// 对jpeg图片做人脸识别
var result = Server.Recognition(jpegData);
// 没数据,进下一轮
if (result.Count <= 0)
{
continue;
}
result.ForEach(f => Log.Information($"识别到人脸:{f.Name} 位置:{f.FaceRect}"));
if (!pipeServer.IsConnected) continue;
foreach (var item in result)
{
// 序列化要发送的数据
byte[] send = ConvertEx.StructToBytes(item);
// 发送数据
await pipeServer.WriteAsync(send);
}
}
catch (Exception ex)
{
Log.Error(ex, "识别人脸报错: ");
}
}
}, TaskCreationOptions.LongRunning); }, TaskCreationOptions.LongRunning);
Log.Information("软件启动成功"); Log.Information("软件启动成功");
......
...@@ -24,34 +24,66 @@ namespace FaceServer ...@@ -24,34 +24,66 @@ namespace FaceServer
return data; return data;
} }
public static async void WriteAsync(this PipeStream @this, byte[] data) public static async Task WriteAsync(this PipeStream @this, byte[] data)
{ {
await @this.WriteAsync(BitConverter.GetBytes(data.Length), 0, sizeof(int)); await @this.WriteAsync(BitConverter.GetBytes(data.Length), 0, sizeof(int));
await @this.WriteAsync(data, 0, data.Length); await @this.WriteAsync(data, 0, data.Length);
} }
public static async Task<byte[]> ReadBytesAsync(this PipeStream @this)
{
try
{
// 尝试读取下一个数据包的长度
var dataLength = await @this.GetDataLengthAsync();
// 读取数据包
byte[] data = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = await @this.ReadAsync(data, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
return data;
}
catch (IOException ex)
{
Log.Error(ex, "读取管道数据时发生 I/O 异常");
throw;
}
catch (Exception ex)
{
Log.Error(ex, "反序列化 FrameData 时发生异常");
throw;
}
}
public static List<byte[]> ReadAllAvailableFrameData(this PipeStream @this) public static List<byte[]> ReadAllAvailableFrameData(this PipeStream @this)
{ {
var allFrameData = new List<byte[]>(); var allFrameData = new List<byte[]>();
// 如果管道里有数据可以取 // 如果管道里有数据可以取
while (@this.InBufferSize != 0) try
{ {
try // 尝试读取下一个数据包的长度
{ var dataLength = @this.GetDataLengthAsync().Result;
var messageData = new List<byte>(); // 读取数据包
do byte[] data = new byte[dataLength];
{ int totalRead = 0;
byte[] buffer = new byte[256]; while (totalRead < dataLength)
int bytesRead = @this.Read(buffer, 0, buffer.Length); {
messageData.AddRange(buffer.Take(bytesRead)); int read = @this.Read(data, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
} }
while (!@this.IsMessageComplete);
allFrameData.Add(messageData.ToArray()); allFrameData.Add(data);
}
catch (EndOfStreamException)
{
break; // 到达流的末尾
} }
catch (IOException ex) catch (IOException ex)
{ {
...@@ -63,24 +95,12 @@ namespace FaceServer ...@@ -63,24 +95,12 @@ namespace FaceServer
Log.Error(ex, "反序列化 FrameData 时发生异常"); Log.Error(ex, "反序列化 FrameData 时发生异常");
throw; throw;
} }
}
return allFrameData; return allFrameData;
} }
private static bool TryReadDataLength(PipeStream pipeStream, out int dataLength)
{
byte[] lengthBuffer = new byte[4];
int bytesRead = pipeStream.Read(lengthBuffer, 0, 4);
if (bytesRead == 4)
{
dataLength = BitConverter.ToInt32(lengthBuffer, 0);
return true;
}
dataLength = 0;
return false;
}
public static async Task<int> GetDataLengthAsync(this PipeStream @this) public static async Task<int> GetDataLengthAsync(this PipeStream @this)
{ {
byte[] lengthBuffer = new byte[4]; byte[] lengthBuffer = new byte[4];
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
public static class ConvertEx
{
public static Byte[] StructToBytes( Object structure)
{
Int32 size = Marshal.SizeOf(structure);
Console.WriteLine(size);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structure, buffer, false);
Byte[] bytes = new Byte[size];
Marshal.Copy(buffer, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
public static T BytesToStruct<T>(Byte[] bytes) where T : struct
{
Int32 size = Marshal.SizeOf(typeof(T));
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, 0, buffer, size);
return (T)Marshal.PtrToStructure(buffer, typeof(T));
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
}
...@@ -79,7 +79,7 @@ public class FaceRecognitionServer ...@@ -79,7 +79,7 @@ public class FaceRecognitionServer
var location = faceLocations.ElementAt(i); var location = faceLocations.ElementAt(i);
// 映射回整个图像的坐标空间 // 映射回整个图像的坐标空间
var faceRect = new Rectangle var faceRect = new RectangleSerializable
( (
location.Left + Roi.X, // 加上ROI的X偏移 location.Left + Roi.X, // 加上ROI的X偏移
location.Top + Roi.Y, // 加上ROI的Y偏移 location.Top + Roi.Y, // 加上ROI的Y偏移
......
using MessagePack; using MessagePack;
using ProtoBuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
public struct FaceRecognitionResult
[StructLayout(LayoutKind.Sequential)]
public struct RectangleSerializable
{ {
public DateTime Timestamp; public int X;
public List<FaceData> Faces; public int Y;
public int Width;
public int Height;
public RectangleSerializable(int x, int y, int w, int h)
{
X = x;
Y = y;
Width = w;
Height = h;
}
public override string ToString()
{
return $"X={X},Y={Y},W={Width},H={Height}";
}
} }
[MessagePackObject]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FaceData public struct FaceData
{ {
[Key(0)] public RectangleSerializable FaceRect;
public Rectangle FaceRect; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
[Key(1)]
public string Name; public string Name;
[Key(2)]
public bool IsIdentified; public bool IsIdentified;
} }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<package id="FaceRecognitionDotNet" version="1.3.0.7" targetFramework="net48" /> <package id="FaceRecognitionDotNet" version="1.3.0.7" targetFramework="net48" />
<package id="MessagePack" version="2.5.140" targetFramework="net48" /> <package id="MessagePack" version="2.5.140" targetFramework="net48" />
<package id="MessagePack.Annotations" version="2.5.140" targetFramework="net48" /> <package id="MessagePack.Annotations" version="2.5.140" targetFramework="net48" />
<package id="MessagePack.ImmutableCollection" version="2.5.140" targetFramework="net48" />
<package id="MessagePackAnalyzer" version="2.5.140" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net48" /> <package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net48" />
<package id="Microsoft.NET.StringTools" version="17.6.3" targetFramework="net48" /> <package id="Microsoft.NET.StringTools" version="17.6.3" targetFramework="net48" />
<package id="OpenCvSharp4" version="4.9.0.20240103" targetFramework="net48" /> <package id="OpenCvSharp4" version="4.9.0.20240103" targetFramework="net48" />
...@@ -11,12 +13,14 @@ ...@@ -11,12 +13,14 @@
<package id="OpenCvSharp4.runtime.win" version="4.9.0.20240103" targetFramework="net48" /> <package id="OpenCvSharp4.runtime.win" version="4.9.0.20240103" targetFramework="net48" />
<package id="OpenCvSharp4.Windows" version="4.9.0.20240103" targetFramework="net48" /> <package id="OpenCvSharp4.Windows" version="4.9.0.20240103" targetFramework="net48" />
<package id="OpenCvSharp4.WpfExtensions" version="4.9.0.20240103" targetFramework="net48" /> <package id="OpenCvSharp4.WpfExtensions" version="4.9.0.20240103" targetFramework="net48" />
<package id="protobuf-net" version="3.2.30" targetFramework="net48" />
<package id="protobuf-net.Core" version="3.2.30" targetFramework="net48" />
<package id="Serilog" version="2.10.0" targetFramework="net48" /> <package id="Serilog" version="2.10.0" targetFramework="net48" />
<package id="Serilog.Enrichers.Thread" version="3.1.0" targetFramework="net48" /> <package id="Serilog.Enrichers.Thread" version="3.1.0" targetFramework="net48" />
<package id="Serilog.Sinks.File" version="5.0.0" targetFramework="net48" /> <package id="Serilog.Sinks.File" version="5.0.0" targetFramework="net48" />
<package id="Serilog.Sinks.Trace" version="3.0.0" targetFramework="net48" /> <package id="Serilog.Sinks.Trace" version="3.0.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" /> <package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Collections.Immutable" version="6.0.0" targetFramework="net48" /> <package id="System.Collections.Immutable" version="7.0.0" targetFramework="net48" />
<package id="System.Drawing.Common" version="7.0.0" targetFramework="net48" /> <package id="System.Drawing.Common" version="7.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" /> <package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
......
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Serilog;
using MessagePack;
namespace FaceServer
{
public static class PipeEx
{
public static void Write(this PipeStream @this, byte[] data)
{
@this.Write(BitConverter.GetBytes(data.Length), 0, sizeof(int));
@this.Write(data, 0, data.Length);
}
public static async Task<byte[]> GetBytes(this PipeStream @this)
{
var len = await GetDataLengthAsync(@this);
var data = await GetData(@this, len);
return data;
}
public static async Task WriteAsync(this PipeStream @this, byte[] data)
{
await @this.WriteAsync(BitConverter.GetBytes(data.Length), 0, sizeof(int));
await @this.WriteAsync(data, 0, data.Length);
}
public static async Task<byte[]> ReadBytesAsync(this PipeStream @this)
{
try
{
// 尝试读取下一个数据包的长度
var dataLength = await @this.GetDataLengthAsync();
// 读取数据包
byte[] data = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = await @this.ReadAsync(data, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
return data;
}
catch (IOException ex)
{
Log.Error(ex, "读取管道数据时发生 I/O 异常");
throw;
}
catch (Exception ex)
{
Log.Error(ex, "反序列化 FrameData 时发生异常");
throw;
}
}
public static List<byte[]> ReadAllAvailableFrameData(this PipeStream @this)
{
var allFrameData = new List<byte[]>();
// 如果管道里有数据可以取
try
{
// 尝试读取下一个数据包的长度
var dataLength = @this.GetDataLengthAsync().Result;
// 读取数据包
byte[] data = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = @this.Read(data, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
allFrameData.Add(data);
}
catch (IOException ex)
{
Log.Error(ex, "读取管道数据时发生 I/O 异常");
throw;
}
catch (Exception ex)
{
Log.Error(ex, "反序列化 FrameData 时发生异常");
throw;
}
return allFrameData;
}
public static async Task<int> GetDataLengthAsync(this PipeStream @this)
{
byte[] lengthBuffer = new byte[4];
await @this.ReadAsync(lengthBuffer, 0, 4);
var dataLength = BitConverter.ToInt32(lengthBuffer, 0);
return dataLength;
}
public static async Task<byte[]> GetData(this PipeStream @this, int dataLength)
{
// 然后读取相应长度的数据
byte[] buffer = new byte[dataLength];
int totalRead = 0;
while (totalRead < dataLength)
{
int read = await @this.ReadAsync(buffer, totalRead, dataLength - totalRead);
if (read == 0)
{
throw new IOException("客户端断开连接");
}
totalRead += read;
}
return buffer;
}
}
}
using FaceServer;
using MessagePack;
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ServerTest
{
[MessagePackObject]
public struct RectangleSerializable
{
[Key(0)]
public int X;
[Key(1)]
public int Y;
[Key(2)]
public int Width;
[Key(3)]
public int Height;
public RectangleSerializable(int x, int y, int w, int h) : this()
{
X = x;
Y = y;
Width = w;
Height = h;
}
public override string ToString()
{
return $"X={X},Y={Y},W={Width},H={Height}";
}
}
[MessagePackObject]
public struct FaceData
{
[Key(0)]
public RectangleSerializable FaceRect;
[Key(1)]
public string Name;
[Key(2)]
public bool IsIdentified;
}
internal class Program
{
private static NamedPipeServerStream pipeServer;
static async Task Main(string[] args)
{
while (true)
{
pipeServer = new NamedPipeServerStream("TEST", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
Console.WriteLine("开始监听");
await pipeServer.WaitForConnectionAsync();
Console.WriteLine("客户端已连接");
await ServerAsync();
Console.WriteLine("客户端已断开连接");
}
}
private static async Task ServerAsync()
{
try
{
var list = new List<FaceData>()
{
new FaceData() { Name = "dsadasd", FaceRect = new RectangleSerializable(1,2,3,4), IsIdentified = true },
new FaceData() { Name = "John", FaceRect = new RectangleSerializable(5,6,7,8), IsIdentified = false },
new FaceData() { Name = "Alice", FaceRect = new RectangleSerializable(9,10,11,12), IsIdentified = true },
new FaceData() { Name = "Bob", FaceRect = new RectangleSerializable(13,14,15,16), IsIdentified = true },
new FaceData() { Name = "Eve", FaceRect = new RectangleSerializable(17,18,19,20), IsIdentified = false },
new FaceData() { Name = "Charlie", FaceRect = new RectangleSerializable(21,22,23,24), IsIdentified = true },
new FaceData() { Name = "David", FaceRect = new RectangleSerializable(25,26,27,28), IsIdentified = true },
new FaceData() { Name = "Grace", FaceRect = new RectangleSerializable(29,30,31,32), IsIdentified = false },
new FaceData() { Name = "Olivia", FaceRect = new RectangleSerializable(33,34,35,36), IsIdentified = true },
new FaceData() { Name = "Sophia", FaceRect = new RectangleSerializable(37,38,39,40), IsIdentified = true }
};
// 处理当前连接的所有数据
while (pipeServer.IsConnected)
{
Console.ReadKey();
Console.WriteLine("Send !");
var raw = MessagePackSerializer.Serialize(list);
await pipeServer.WriteAsync(raw);
}
}
catch (Exception ex)
{
Console.WriteLine( $"处理管道数据时发生错误{ex}");
}
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ServerTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServerTest")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("0a3c84af-ff06-4770-b00d-f938a1431d42")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{0A3C84AF-FF06-4770-B00D-F938A1431D42}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ServerTest</RootNamespace>
<AssemblyName>ServerTest</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="MessagePack, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL">
<HintPath>..\packages\MessagePack.2.5.140\lib\netstandard2.0\MessagePack.dll</HintPath>
</Reference>
<Reference Include="MessagePack.Annotations, Version=2.5.0.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be, processorArchitecture=MSIL">
<HintPath>..\packages\MessagePack.Annotations.2.5.140\lib\netstandard2.0\MessagePack.Annotations.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.NET.StringTools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.NET.StringTools.17.6.3\lib\net472\Microsoft.NET.StringTools.dll</HintPath>
</Reference>
<Reference Include="Serilog, Version=2.0.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
<HintPath>..\packages\Serilog.2.10.0\lib\net46\Serilog.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.6.0.0\lib\net461\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PipeEx.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MessagePack" version="2.5.140" targetFramework="net48" />
<package id="MessagePack.Annotations" version="2.5.140" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net48" />
<package id="Microsoft.NET.StringTools" version="17.6.3" targetFramework="net48" />
<package id="Serilog" version="2.10.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Collections.Immutable" version="6.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Reflection.Emit" version="4.7.0" targetFramework="net48" />
<package id="System.Reflection.Emit.Lightweight" version="4.7.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
</packages>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment