commit fadf701ff2271471af70445b9632e6fdfb0f00ae parent b59baa8d7a92419c4accc307082f66c79b6ee1ed Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com> Date: Mon, 14 Sep 2020 14:16:54 +0100 Formatted NetSharp according to StyleCop analyzer extensions (with a few exceptions). Removed unnecessary messages in Benchmarks project. Diffstat:
37 files changed, 885 insertions(+), 804 deletions(-)
diff --git a/NetSharp/NetSharp.Benchmarks/AssemblyAttributes.cs b/NetSharp/NetSharp.Benchmarks/AssemblyAttributes.cs @@ -0,0 +1,5 @@ +using System.Resources; + + + +[assembly: NeutralResourcesLanguage("en")] +\ No newline at end of file diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedMultiClientRawDatagramBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedMultiClientRawDatagramBenchmark.cs @@ -31,7 +31,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); @@ -88,11 +88,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedSingleClientRawDatagramBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedSingleClientRawDatagramBenchmark.cs @@ -31,7 +31,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); @@ -88,11 +88,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderMultiClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderMultiClientBenchmark.cs @@ -32,7 +32,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); @@ -85,11 +85,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderSingleClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderSingleClientBenchmark.cs @@ -32,7 +32,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); @@ -85,11 +85,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterAsyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterAsyncBenchmark.cs @@ -48,11 +48,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); rawSocket.Bind(Program.Constants.ClientEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterSyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterSyncBenchmark.cs @@ -48,11 +48,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); rawSocket.Bind(Program.Constants.ClientEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedMultiClientRawStreamBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedMultiClientRawStreamBenchmark.cs @@ -32,7 +32,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); @@ -93,11 +93,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedSingleClientRawStreamBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedSingleClientRawStreamBenchmark.cs @@ -31,7 +31,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); @@ -92,11 +92,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderMultiClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderMultiClientBenchmark.cs @@ -33,7 +33,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); @@ -114,11 +114,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderSingleClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderSingleClientBenchmark.cs @@ -32,7 +32,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks try { - int id = (int) idObj; + int id = (int)idObj; BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); @@ -113,11 +113,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ServerEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterAsyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterAsyncBenchmark.cs @@ -78,11 +78,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks /// <inheritdoc /> public async Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ClientEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterSyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterSyncBenchmark.cs @@ -78,11 +78,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks /// <inheritdoc /> public Task RunAsync() { - if (Program.Constants.PacketCount > 10_000) - { - Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); - } - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ClientEndPoint); diff --git a/NetSharp/NetSharp.Benchmarks/Program.cs b/NetSharp/NetSharp.Benchmarks/Program.cs @@ -3,11 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Reflection; -using System.Resources; using System.Text; -[assembly: NeutralResourcesLanguage("en")] - namespace NetSharp.Benchmarks { internal class Program @@ -28,7 +25,7 @@ namespace NetSharp.Benchmarks Type[] interfaces = type.GetInterfaces(); if (interfaces.Contains(typeof(INetSharpBenchmark))) { - Benchmarks.Add((INetSharpBenchmark) Activator.CreateInstance(type)); + Benchmarks.Add((INetSharpBenchmark)Activator.CreateInstance(type)); } } } @@ -116,7 +113,8 @@ namespace NetSharp.Benchmarks private static readonly IPAddress DefaultAddress = IPAddress.Loopback; #if DEBUG - public const int PacketSize = 4096, PacketCount = 10, ClientCount = 1; + // Packet counts of over 10_000 can take a long time, depending on the packet size and number of clients + public const int PacketSize = 4096, PacketCount = 10_000, ClientCount = 1; #else // RELEASE public const int PacketSize = 8192, PacketCount = 1_000_000, ClientCount = 10; #endif diff --git a/NetSharp/NetSharp.Examples/AssemblyAttributes.cs b/NetSharp/NetSharp.Examples/AssemblyAttributes.cs @@ -0,0 +1,5 @@ +using System.Resources; + + + +[assembly: NeutralResourcesLanguage("en")] +\ No newline at end of file diff --git a/NetSharp/NetSharp.Examples/Program.cs b/NetSharp/NetSharp.Examples/Program.cs @@ -3,11 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Reflection; -using System.Resources; using System.Text; -[assembly: NeutralResourcesLanguage("en")] - namespace NetSharp.Examples { internal class Program @@ -28,7 +25,7 @@ namespace NetSharp.Examples Type[] interfaces = type.GetInterfaces(); if (interfaces.Contains(typeof(INetSharpExample))) { - Examples.Add((INetSharpExample) Activator.CreateInstance(type)); + Examples.Add((INetSharpExample)Activator.CreateInstance(type)); } } } diff --git a/NetSharp/NetSharp.Tests/AssemblyAttributes.cs b/NetSharp/NetSharp.Tests/AssemblyAttributes.cs @@ -0,0 +1,5 @@ +using System.Resources; + + + +[assembly: NeutralResourcesLanguage("en")] +\ No newline at end of file diff --git a/NetSharp/NetSharp.Tests/Program.cs b/NetSharp/NetSharp.Tests/Program.cs @@ -1,11 +1,8 @@ using System.Net; -using System.Resources; using System.Text; using Xunit; -[assembly: NeutralResourcesLanguage("en")] - namespace NetSharp.Tests { public class Program diff --git a/NetSharp/NetSharp/AssemblyAttributes.cs b/NetSharp/NetSharp/AssemblyAttributes.cs @@ -3,4 +3,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("NetSharp.Benchmarks", AllInternalsVisible = true)] [assembly: InternalsVisibleTo("NetSharp.Tests", AllInternalsVisible = true)] -[assembly: NeutralResourcesLanguage("en")] -\ No newline at end of file +[assembly: NeutralResourcesLanguage("en")] diff --git a/NetSharp/NetSharp/GlobalSuppressions.cs b/NetSharp/NetSharp/GlobalSuppressions.cs @@ -0,0 +1,10 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1623:Property summary documentation should match accessors", Justification = "\'Gets\' and \'Sets\' are unnecessary and can be inferred for single accessor properties.")] +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "Headers for all source files are unnecessary, as a license already exists in the git projet root.")] +[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this", Justification = "\'this.\' is unnecessary, as it can be inferred from just reading the code.")] diff --git a/NetSharp/NetSharp/Interfaces/IRawNetworkReader.cs b/NetSharp/NetSharp/Interfaces/IRawNetworkReader.cs @@ -19,4 +19,4 @@ /// </param> public void Start(ushort concurrentTasks); } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Interfaces/IRawNetworkWriter.cs b/NetSharp/NetSharp/Interfaces/IRawNetworkWriter.cs @@ -80,4 +80,4 @@ namespace NetSharp.Interfaces /// </returns> public ValueTask<int> WriteAsync(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None); } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/NetSharp.csproj b/NetSharp/NetSharp/NetSharp.csproj @@ -1,66 +1,78 @@ <Project Sdk="Microsoft.NET.Sdk"> - <PropertyGroup> - <Nullable>enable</Nullable> - <TargetFramework>netstandard2.1</TargetFramework> - <AnalysisLevel>latest</AnalysisLevel> - <Configurations>Debug;Release</Configurations> - </PropertyGroup> + <PropertyGroup> + <Nullable>enable</Nullable> + <TargetFramework>netstandard2.1</TargetFramework> + <AnalysisLevel>latest</AnalysisLevel> + <Configurations>Debug;Release</Configurations> + </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> - <DocumentationFile>NetSharp.xml</DocumentationFile> - <GeneratePackageOnBuild>true</GeneratePackageOnBuild> - <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> - <Authors>Mikołaj Lenczewski</Authors> - <Company>NetSharp</Company> - <Version>0.1.7</Version> - <PackageLicenseFile>LICENSE</PackageLicenseFile> - <PackageProjectUrl>https://github.com/mblenczewski/NetSharp</PackageProjectUrl> - <Description>A networking library for C#, focusing on performance and built on top of SocketAsyncEventArgs.</Description> - <RepositoryUrl>https://github.com/mblenczewski/NetSharp.git</RepositoryUrl> - <RepositoryType>git</RepositoryType> - <PackageTags>networking</PackageTags> - <IncludeSymbols>true</IncludeSymbols> - <SymbolPackageFormat>snupkg</SymbolPackageFormat> - </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> + <DocumentationFile>NetSharp.xml</DocumentationFile> + <GeneratePackageOnBuild>true</GeneratePackageOnBuild> + <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> + <Authors>Mikołaj Lenczewski</Authors> + <Company>NetSharp</Company> + <Version>0.1.7</Version> + <PackageLicenseFile>LICENSE</PackageLicenseFile> + <PackageProjectUrl>https://github.com/mblenczewski/NetSharp</PackageProjectUrl> + <Description>A networking library for C#, focusing on performance and built on top of SocketAsyncEventArgs.</Description> + <RepositoryUrl>https://github.com/mblenczewski/NetSharp.git</RepositoryUrl> + <RepositoryType>git</RepositoryType> + <PackageTags>networking</PackageTags> + <IncludeSymbols>true</IncludeSymbols> + <SymbolPackageFormat>snupkg</SymbolPackageFormat> + </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> - <DocumentationFile>NetSharp.xml</DocumentationFile> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <DebugType>full</DebugType> - <DebugSymbols>true</DebugSymbols> - </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <DocumentationFile>NetSharp.xml</DocumentationFile> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <DebugSymbols>true</DebugSymbols> + </PropertyGroup> - <ItemGroup> - <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0"> - <PrivateAssets>all</PrivateAssets> - <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> - </PackageReference> - <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> - </ItemGroup> + <ItemGroup> + <None Remove="stylecop.json" /> + </ItemGroup> - <ItemGroup> - <None Include="..\..\LICENSE"> - <Pack>True</Pack> - <PackagePath></PackagePath> - </None> - </ItemGroup> + <ItemGroup> + <AdditionalFiles Include="stylecop.json" /> + </ItemGroup> - <ItemGroup> - <Compile Update="Properties\Resources.Designer.cs"> - <DesignTime>True</DesignTime> - <AutoGen>True</AutoGen> - <DependentUpon>Resources.resx</DependentUpon> - </Compile> - </ItemGroup> + <ItemGroup> + <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> + <PackageReference Include="StyleCop.Analyzers" Version="1.1.118"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + </ItemGroup> - <ItemGroup> - <EmbeddedResource Update="Properties\Resources.pl-PL.resx"> - <Generator>ResXFileCodeGenerator</Generator> - </EmbeddedResource> - <EmbeddedResource Update="Properties\Resources.resx"> - <Generator>ResXFileCodeGenerator</Generator> - <LastGenOutput>Resources.Designer.cs</LastGenOutput> - </EmbeddedResource> - </ItemGroup> + <ItemGroup> + <None Include="..\..\LICENSE"> + <Pack>True</Pack> + <PackagePath></PackagePath> + </None> + </ItemGroup> + + <ItemGroup> + <Compile Update="Properties\Resources.Designer.cs"> + <DesignTime>True</DesignTime> + <AutoGen>True</AutoGen> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + </ItemGroup> + + <ItemGroup> + <EmbeddedResource Update="Properties\Resources.pl-PL.resx"> + <Generator>ResXFileCodeGenerator</Generator> + </EmbeddedResource> + <EmbeddedResource Update="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + </ItemGroup> </Project> \ No newline at end of file diff --git a/NetSharp/NetSharp/NetSharp.xml b/NetSharp/NetSharp/NetSharp.xml @@ -103,11 +103,6 @@ A strongly-typed resource class, for looking up localized strings, etc. </summary> </member> - <member name="P:NetSharp.Properties.Resources.ResourceManager"> - <summary> - Returns the cached ResourceManager instance used by this class. - </summary> - </member> <member name="P:NetSharp.Properties.Resources.Culture"> <summary> Overrides the current thread's CurrentUICulture property for all @@ -129,6 +124,11 @@ Looks up a localized string similar to The maximum pooled message size must be greater than 0 bytes. </summary> </member> + <member name="P:NetSharp.Properties.Resources.ResourceManager"> + <summary> + Returns the cached ResourceManager instance used by this class. + </summary> + </member> <member name="T:NetSharp.Raw.Datagram.RawDatagramRequestHandler"> <summary> Represents a method that handles a request received by a <see cref="T:NetSharp.Raw.Datagram.RawDatagramNetworkReader" />. @@ -155,6 +155,9 @@ </summary> </member> <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkReader.#ctor(System.Net.Sockets.Socket@,NetSharp.Raw.Datagram.RawDatagramRequestHandler,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> + <inheritdoc cref="M:NetSharp.Raw.RawNetworkReaderBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)" /> + </member> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkReader.Start(System.UInt16)"> <inheritdoc /> </member> <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkReader.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> @@ -169,39 +172,36 @@ <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkReader.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkReader.Start(System.UInt16)"> - <inheritdoc /> - </member> <member name="T:NetSharp.Raw.Datagram.RawDatagramNetworkWriter"> <summary> Implements a raw network writer using a datagram-based protocol. </summary> </member> <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> - <inheritdoc /> + <inheritdoc cref="M:NetSharp.Raw.RawNetworkWriterBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"/> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.Read(System.Net.EndPoint@,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.CreateStateObject"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.ReadAsync(System.Net.EndPoint,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.DestroyStateObject(System.Net.Sockets.SocketAsyncEventArgs)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.Write(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.WriteAsync(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.Read(System.Net.EndPoint@,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.ReadAsync(System.Net.EndPoint,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.CreateStateObject"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.Write(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.DestroyStateObject(System.Net.Sockets.SocketAsyncEventArgs)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.WriteAsync(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Datagram.RawDatagramNetworkWriter.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc /> </member> <member name="T:NetSharp.Raw.RawNetworkConnectionBase"> @@ -212,13 +212,13 @@ <member name="F:NetSharp.Raw.RawNetworkConnectionBase.DefaultMaxPooledBufferSize"> <summary> The maximum size of a pooled buffer that can be used with the <see cref="P:System.Buffers.ArrayPool`1.Shared" /> property, before a new custom pool must - be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs + be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs. </summary> </member> <member name="F:NetSharp.Raw.RawNetworkConnectionBase.DefaultMaxPooledBuffersPerBucket"> <summary> The maximum number of pooled buffers per bucket that can be used with the <see cref="P:System.Buffers.ArrayPool`1.Shared" /> property, before a new custom - pool must be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs + pool must be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs. </summary> </member> <member name="F:NetSharp.Raw.RawNetworkConnectionBase.MaxDatagramSize"> @@ -228,7 +228,7 @@ </member> <member name="M:NetSharp.Raw.RawNetworkConnectionBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> <summary> - Constructs a new instance of the <see cref="T:NetSharp.Raw.RawNetworkConnectionBase" /> class. + Initialises a new instance of the <see cref="T:NetSharp.Raw.RawNetworkConnectionBase"/> class. </summary> <param name="rawConnection"> The underlying <see cref="T:System.Net.Sockets.Socket" /> to use for the connection. @@ -253,7 +253,7 @@ </member> <member name="P:NetSharp.Raw.RawNetworkConnectionBase.BufferPool"> <summary> - The object pool to use to pool byte buffer instance + The object pool to use to pool byte buffer instance. </summary> </member> <member name="P:NetSharp.Raw.RawNetworkConnectionBase.Connection"> @@ -266,6 +266,9 @@ The default endpoint to use to represent remote clients. </summary> </member> + <member name="M:NetSharp.Raw.RawNetworkConnectionBase.Dispose"> + <inheritdoc /> + </member> <member name="M:NetSharp.Raw.RawNetworkConnectionBase.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc cref="T:NetSharp.Utils.SlimObjectPool`1.CanReuseObjectPredicate" /> </member> @@ -287,42 +290,42 @@ <summary> Allows for inheritors to dispose of their own resources. </summary> + <param name="disposing"> + Whether the <see cref="M:NetSharp.Raw.RawNetworkConnectionBase.Dispose"/> method is being called. + </param> </member> <member name="M:NetSharp.Raw.RawNetworkConnectionBase.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc cref="T:NetSharp.Utils.SlimObjectPool`1.ResetObjectDelegate" /> </member> - <member name="M:NetSharp.Raw.RawNetworkConnectionBase.Dispose"> - <inheritdoc /> - </member> <member name="T:NetSharp.Raw.RawNetworkReaderBase"> <summary> Provides fields and methods common to all network reader connections. </summary> </member> <member name="M:NetSharp.Raw.RawNetworkReaderBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> - <inheritdoc /> + <inheritdoc cref="M:NetSharp.Raw.RawNetworkConnectionBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"/> </member> <member name="P:NetSharp.Raw.RawNetworkReaderBase.ShutdownToken"> <summary> The <see cref="T:System.Threading.CancellationToken" /> for the network reader. </summary> </member> - <member name="M:NetSharp.Raw.RawNetworkReaderBase.Dispose(System.Boolean)"> - <inheritdoc /> - </member> <member name="M:NetSharp.Raw.RawNetworkReaderBase.Shutdown"> <inheritdoc /> </member> <member name="M:NetSharp.Raw.RawNetworkReaderBase.Start(System.UInt16)"> <inheritdoc /> </member> + <member name="M:NetSharp.Raw.RawNetworkReaderBase.Dispose(System.Boolean)"> + <inheritdoc /> + </member> <member name="T:NetSharp.Raw.RawNetworkWriterBase"> <summary> Provides fields and methods common to all network writer connections. </summary> </member> <member name="M:NetSharp.Raw.RawNetworkWriterBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> - <inheritdoc /> + <inheritdoc cref="M:NetSharp.Raw.RawNetworkConnectionBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"/> </member> <member name="M:NetSharp.Raw.RawNetworkWriterBase.Read(System.Net.EndPoint@,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> @@ -362,6 +365,9 @@ </summary> </member> <member name="M:NetSharp.Raw.Stream.RawStreamNetworkReader.#ctor(System.Net.Sockets.Socket@,NetSharp.Raw.Stream.RawStreamRequestHandler,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> + <inheritdoc cref="M:NetSharp.Raw.RawNetworkReaderBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"/> + </member> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkReader.Start(System.UInt16)"> <inheritdoc /> </member> <member name="M:NetSharp.Raw.Stream.RawStreamNetworkReader.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> @@ -376,41 +382,69 @@ <member name="M:NetSharp.Raw.Stream.RawStreamNetworkReader.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkReader.Start(System.UInt16)"> - <inheritdoc /> - </member> <member name="T:NetSharp.Raw.Stream.RawStreamNetworkWriter"> <summary> Implements a raw network writer using a stream-based protocol. </summary> </member> <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)"> - <inheritdoc /> + <inheritdoc cref="M:NetSharp.Raw.RawNetworkWriterBase.#ctor(System.Net.Sockets.Socket@,System.Net.EndPoint,System.Int32,System.Int32,System.UInt32)" /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.Read(System.Net.EndPoint@,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.CreateStateObject"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.ReadAsync(System.Net.EndPoint,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.DestroyStateObject(System.Net.Sockets.SocketAsyncEventArgs)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.Write(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.WriteAsync(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.Read(System.Net.EndPoint@,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.CanReuseStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.ReadAsync(System.Net.EndPoint,System.Memory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.CreateStateObject"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.Write(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.DestroyStateObject(System.Net.Sockets.SocketAsyncEventArgs)"> <inheritdoc /> </member> - <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.WriteAsync(System.Net.EndPoint,System.ReadOnlyMemory{System.Byte},System.Net.Sockets.SocketFlags)"> + <member name="M:NetSharp.Raw.Stream.RawStreamNetworkWriter.ResetStateObject(System.Net.Sockets.SocketAsyncEventArgs@)"> <inheritdoc /> </member> + <member name="T:NetSharp.Raw.Stream.RawStreamPacket"> + <summary> + Provides helper methods to manipulate the binary packet format used by stream network handlers. + </summary> + </member> + <member name="M:NetSharp.Raw.Stream.RawStreamPacket.Serialise(System.Memory{System.Byte}@,NetSharp.Raw.Stream.RawStreamPacketHeader@,System.ReadOnlyMemory{System.Byte}@)"> + <summary> + Serialises the given <paramref name="packetHeader" /> and <paramref name="packetData" /> into the given <paramref name="buffer" />. + </summary> + <param name="buffer"> + The buffer into which the packet should be serialised. Must be at least of size <see cref="F:NetSharp.Raw.Stream.RawStreamPacketHeader.TotalSize" /> + the size + of the user data given by <paramref name="packetHeader" />. + </param> + <param name="packetHeader"> + The header containing metatdata abut the raw stream packet. + </param> + <param name="packetData"> + The user data held in the raw stream packet. + </param> + </member> + <member name="M:NetSharp.Raw.Stream.RawStreamPacket.TotalPacketSize(NetSharp.Raw.Stream.RawStreamPacketHeader@)"> + <summary> + Calculates the total size of a raw stream packet, using the packet data size in the given <paramref name="packetHeader" />. + </summary> + <param name="packetHeader"> + The header for which to calculate the total packet size. + </param> + <returns> + The total size of a raw stream packet with the given <paramref name="packetHeader" />. + </returns> + </member> <member name="T:NetSharp.Raw.Stream.RawStreamPacketHeader"> <summary> Holds metadata about a raw stream packet. @@ -428,7 +462,7 @@ </member> <member name="M:NetSharp.Raw.Stream.RawStreamPacketHeader.#ctor(System.Int32)"> <summary> - Constructs a new instance of the <see cref="T:NetSharp.Raw.Stream.RawStreamPacketHeader" /> struct. + Initialises a new instance of the <see cref="T:NetSharp.Raw.Stream.RawStreamPacketHeader"/> struct. </summary> <param name="dataSize"> The size of the user supplied data segment. @@ -453,47 +487,11 @@ The buffer into which to serialise the current instance. Must be at least of size <see cref="F:NetSharp.Raw.Stream.RawStreamPacketHeader.TotalSize" />. </param> </member> - <member name="T:NetSharp.Raw.Stream.RawStreamPacket"> - <summary> - Provides helper methods to manipulate the binary packet format used by stream network handlers. - </summary> - </member> - <member name="M:NetSharp.Raw.Stream.RawStreamPacket.Serialise(System.Memory{System.Byte}@,NetSharp.Raw.Stream.RawStreamPacketHeader@,System.ReadOnlyMemory{System.Byte}@)"> - <summary> - Serialises the given <paramref name="packetHeader" /> and <paramref name="packetData" /> into the given <paramref name="buffer" />. - </summary> - <param name="buffer"> - The buffer into which the packet should be serialised. Must be at least of size <see cref="F:NetSharp.Raw.Stream.RawStreamPacketHeader.TotalSize" /> + the size - of the user data given by <paramref name="packetHeader" />. - </param> - <param name="packetHeader"> - The header containing metatdata abut the raw stream packet. - </param> - <param name="packetData"> - The user data held in the raw stream packet. - </param> - </member> - <member name="M:NetSharp.Raw.Stream.RawStreamPacket.TotalPacketSize(NetSharp.Raw.Stream.RawStreamPacketHeader@)"> - <summary> - Calculates the total size of a raw stream packet, using the packet data size in the given <paramref name="packetHeader" />. - </summary> - <param name="packetHeader"> - The header for which to calculate the total packet size. - </param> - <returns> - The total size of a raw stream packet with the given <paramref name="packetHeader" />. - </returns> - </member> <member name="T:NetSharp.Utils.Conversion.EndianAwareBitConverter"> <summary> Wraps the <see cref="T:System.BitConverter" /> class to provide conversion that is endian-aware. </summary> </member> - <member name="M:NetSharp.Utils.Conversion.EndianAwareBitConverter.ReverseAsNeeded(System.Span{System.Byte},System.Boolean)"> - <summary> - Reverses the given bytes if the endian-nes doesn't match. - </summary> - </member> <member name="M:NetSharp.Utils.Conversion.EndianAwareBitConverter.GetBytes(System.Boolean,System.Boolean)"> <inheritdoc cref="M:System.BitConverter.GetBytes(System.Boolean)" /> </member> @@ -554,6 +552,11 @@ <member name="M:NetSharp.Utils.Conversion.EndianAwareBitConverter.ToUInt64(System.Span{System.Byte},System.Boolean)"> <inheritdoc cref="M:System.BitConverter.ToUInt64(System.ReadOnlySpan{System.Byte})" /> </member> + <member name="M:NetSharp.Utils.Conversion.EndianAwareBitConverter.ReverseAsNeeded(System.Span{System.Byte},System.Boolean)"> + <summary> + Reverses the given bytes if the endian-nes doesn't match. + </summary> + </member> <member name="T:NetSharp.Utils.SlimObjectPool`1"> <summary> Provides a lightweight implementation of an object pool for classes. @@ -562,29 +565,9 @@ The type of item stored in the pool. </typeparam> </member> - <member name="M:NetSharp.Utils.SlimObjectPool`1.#ctor(NetSharp.Utils.SlimObjectPool{`0}.CreateObjectDelegate@,NetSharp.Utils.SlimObjectPool{`0}.ResetObjectDelegate@,NetSharp.Utils.SlimObjectPool{`0}.DestroyObjectDelegate@,NetSharp.Utils.SlimObjectPool{`0}.CanReuseObjectPredicate@,System.Collections.Concurrent.IProducerConsumerCollection{`0}@)"> - <summary> - Constructs a new instance of the <see cref="T:NetSharp.Utils.SlimObjectPool`1" /> class. - </summary> - <param name="createDelegate"> - The delegate method to use to create new pooled object instances. - </param> - <param name="resetDelegate"> - The delegate method to use to reset used pooled object instances. - </param> - <param name="destroyDelegate"> - The delegate method to use to destroy pooled object instances that cannot be reused. - </param> - <param name="rebufferPredicate"> - The delegate method to use to decide whether an instance can be reused. - </param> - <param name="baseCollection"> - The underlying pooled object buffer to use. - </param> - </member> - <member name="M:NetSharp.Utils.SlimObjectPool`1.#ctor(NetSharp.Utils.SlimObjectPool{`0}.CreateObjectDelegate@,NetSharp.Utils.SlimObjectPool{`0}.ResetObjectDelegate@,NetSharp.Utils.SlimObjectPool{`0}.DestroyObjectDelegate@,NetSharp.Utils.SlimObjectPool{`0}.CanReuseObjectPredicate@)"> + <member name="M:NetSharp.Utils.SlimObjectPool`1.#ctor(NetSharp.Utils.SlimObjectPool{`0}.CreateObjectDelegate,NetSharp.Utils.SlimObjectPool{`0}.ResetObjectDelegate,NetSharp.Utils.SlimObjectPool{`0}.DestroyObjectDelegate,NetSharp.Utils.SlimObjectPool{`0}.CanReuseObjectPredicate)"> <summary> - Constructs a new instance of the <see cref="T:NetSharp.Utils.SlimObjectPool`1" /> class. + Initialises a new instance of the <see cref="T:NetSharp.Utils.SlimObjectPool`1"/> class. </summary> <param name="createDelegate"> The delegate method to use to create new pooled object instances. diff --git a/NetSharp/NetSharp/Properties/Resources.Designer.cs b/NetSharp/NetSharp/Properties/Resources.Designer.cs @@ -8,10 +8,8 @@ // </auto-generated> //------------------------------------------------------------------------------ -namespace NetSharp.Properties { - using System; - - +namespace NetSharp.Properties +{ /// <summary> /// A strongly-typed resource class, for looking up localized strings, etc. /// </summary> @@ -22,69 +20,82 @@ namespace NetSharp.Properties { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - + internal class Resources + { private static global::System.Globalization.CultureInfo resourceCulture; - + + private static global::System.Resources.ResourceManager resourceMan; + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { + internal Resources() + { } - - /// <summary> - /// Returns the cached ResourceManager instance used by this class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NetSharp.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - + /// <summary> /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// </summary> [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { + internal static global::System.Globalization.CultureInfo Culture + { + get + { return resourceCulture; } - set { + set + { resourceCulture = value; } } - + /// <summary> /// Looks up a localized string similar to Cannot rent a temporary buffer of size: {0} bytes. The maximum temporary buffer size is {1} bytes. /// </summary> - internal static string RawDatagramNetworkReaderRentedBufferSizeError { - get { + internal static string RawDatagramNetworkReaderRentedBufferSizeError + { + get + { return ResourceManager.GetString("RawDatagramNetworkReaderRentedBufferSizeError", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to The datagram size must be between 0 and 65507 bytes. /// </summary> - internal static string RawDatagramSizeError { - get { + internal static string RawDatagramSizeError + { + get + { return ResourceManager.GetString("RawDatagramSizeError", resourceCulture); } } - + /// <summary> /// Looks up a localized string similar to The maximum pooled message size must be greater than 0 bytes. /// </summary> - internal static string RawStreamMessageSizeUnderflow { - get { + internal static string RawStreamMessageSizeUnderflow + { + get + { return ResourceManager.GetString("RawStreamMessageSizeUnderflow", resourceCulture); } } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if (object.ReferenceEquals(resourceMan, null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NetSharp.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } } } diff --git a/NetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkReader.cs b/NetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkReader.cs @@ -24,7 +24,10 @@ namespace NetSharp.Raw.Datagram /// Whether there exists a response to be sent back to the remote endpoint. /// </returns> // TODO implement this in a better, more robust and extensible way - public delegate bool RawDatagramRequestHandler(EndPoint remoteEndPoint, in ReadOnlyMemory<byte> requestBuffer, int receivedRequestBytes, + public delegate bool RawDatagramRequestHandler( + EndPoint remoteEndPoint, + in ReadOnlyMemory<byte> requestBuffer, + int receivedRequestBytes, in Memory<byte> responseBuffer); /// <summary> @@ -36,12 +39,17 @@ namespace NetSharp.Raw.Datagram private readonly RawDatagramRequestHandler requestHandler; - /// <inheritdoc /> - public RawDatagramNetworkReader(ref Socket rawConnection, RawDatagramRequestHandler? requestHandler, EndPoint defaultEndPoint, int datagramSize, - int pooledBuffersPerBucket = 50, uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, datagramSize, - pooledBuffersPerBucket, preallocatedStateObjects) + /// <inheritdoc cref="RawNetworkReaderBase(ref Socket, EndPoint, int, int, uint)" /> + public RawDatagramNetworkReader( + ref Socket rawConnection, + RawDatagramRequestHandler? requestHandler, + EndPoint defaultEndPoint, + int datagramSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) + : base(ref rawConnection, defaultEndPoint, datagramSize, pooledBuffersPerBucket, preallocatedStateObjects) { - if (datagramSize <= 0 || MaxDatagramSize < datagramSize) + if (datagramSize <= 0 || datagramSize > MaxDatagramSize) { throw new ArgumentOutOfRangeException(nameof(datagramSize), datagramSize, Properties.Resources.RawDatagramSizeError); } @@ -51,7 +59,47 @@ namespace NetSharp.Raw.Datagram this.requestHandler = requestHandler ?? DefaultRequestHandler; } - private static bool DefaultRequestHandler(EndPoint remoteEndPoint, in ReadOnlyMemory<byte> requestBuffer, int receivedRequestBytes, + /// <inheritdoc /> + public override void Start(ushort concurrentReadTasks) + { + for (ushort i = 0; i < concurrentReadTasks; i++) + { + StartDefaultReceiveFrom(); + } + } + + /// <inheritdoc /> + protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) + { + return true; + } + + /// <inheritdoc /> + protected override SocketAsyncEventArgs CreateStateObject() + { + SocketAsyncEventArgs instance = new SocketAsyncEventArgs { RemoteEndPoint = DefaultEndPoint }; + instance.Completed += HandleIoCompleted; + + return instance; + } + + /// <inheritdoc /> + protected override void DestroyStateObject(SocketAsyncEventArgs instance) + { + instance.Completed -= HandleIoCompleted; + instance.Dispose(); + } + + /// <inheritdoc /> + protected override void ResetStateObject(ref SocketAsyncEventArgs instance) + { + instance.RemoteEndPoint = DefaultEndPoint; + } + + private static bool DefaultRequestHandler( + EndPoint remoteEndPoint, + in ReadOnlyMemory<byte> requestBuffer, + int receivedRequestBytes, in Memory<byte> responseBuffer) { return requestBuffer.TryCopyTo(responseBuffer); @@ -144,42 +192,5 @@ namespace NetSharp.Raw.Datagram CompleteSendTo(args); } - - /// <inheritdoc /> - protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) - { - return true; - } - - /// <inheritdoc /> - protected override SocketAsyncEventArgs CreateStateObject() - { - SocketAsyncEventArgs instance = new SocketAsyncEventArgs { RemoteEndPoint = DefaultEndPoint }; - instance.Completed += HandleIoCompleted; - - return instance; - } - - /// <inheritdoc /> - protected override void DestroyStateObject(SocketAsyncEventArgs instance) - { - instance.Completed -= HandleIoCompleted; - instance.Dispose(); - } - - /// <inheritdoc /> - protected override void ResetStateObject(ref SocketAsyncEventArgs instance) - { - instance.RemoteEndPoint = DefaultEndPoint; - } - - /// <inheritdoc /> - public override void Start(ushort concurrentReadTasks) - { - for (ushort i = 0; i < concurrentReadTasks; i++) - { - StartDefaultReceiveFrom(); - } - } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkWriter.cs b/NetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkWriter.cs @@ -14,11 +14,16 @@ namespace NetSharp.Raw.Datagram { private readonly int datagramSize; - /// <inheritdoc /> - public RawDatagramNetworkWriter(ref Socket rawConnection, EndPoint defaultEndPoint, int datagramSize, int pooledBuffersPerBucket = 50, - uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, datagramSize, pooledBuffersPerBucket, preallocatedStateObjects) + /// <inheritdoc cref="RawNetworkWriterBase(ref Socket, EndPoint, int, int, uint)"/> + public RawDatagramNetworkWriter( + ref Socket rawConnection, + EndPoint defaultEndPoint, + int datagramSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) + : base(ref rawConnection, defaultEndPoint, datagramSize, pooledBuffersPerBucket, preallocatedStateObjects) { - if (datagramSize <= 0 || MaxDatagramSize < datagramSize) + if (datagramSize <= 0 || datagramSize > MaxDatagramSize) { throw new ArgumentOutOfRangeException(nameof(datagramSize), datagramSize, Resources.RawDatagramSizeError); } @@ -26,98 +31,6 @@ namespace NetSharp.Raw.Datagram this.datagramSize = datagramSize; } - private void CompleteReceiveFrom(SocketAsyncEventArgs args) - { - PacketReadToken token = (PacketReadToken) args.UserToken; - - byte[] receiveBuffer = args.Buffer; - - switch (args.SocketError) - { - case SocketError.Success: - receiveBuffer.CopyTo(token.UserBuffer); - token.CompletionSource.SetResult(args.BytesTransferred); - break; - - case SocketError.OperationAborted: - token.CompletionSource.SetCanceled(); - break; - - default: - token.CompletionSource.SetException(new SocketException((int) args.SocketError)); - break; - } - - BufferPool.Return(receiveBuffer, true); - ArgsPool.Return(args); - } - - private void CompleteSendTo(SocketAsyncEventArgs args) - { - PacketWriteToken token = (PacketWriteToken) args.UserToken; - - byte[] sendBuffer = args.Buffer; - - switch (args.SocketError) - { - case SocketError.Success: - token.CompletionSource.SetResult(args.BytesTransferred); - break; - - case SocketError.OperationAborted: - token.CompletionSource.SetCanceled(); - break; - - default: - token.CompletionSource.SetException(new SocketException((int) args.SocketError)); - break; - } - - BufferPool.Return(sendBuffer, true); - ArgsPool.Return(args); - } - - private void HandleIoCompleted(object sender, SocketAsyncEventArgs args) - { - switch (args.LastOperation) - { - case SocketAsyncOperation.SendTo: - CompleteSendTo(args); - break; - - case SocketAsyncOperation.ReceiveFrom: - CompleteReceiveFrom(args); - break; - } - } - - /// <inheritdoc /> - protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) - { - return true; - } - - /// <inheritdoc /> - protected override SocketAsyncEventArgs CreateStateObject() - { - SocketAsyncEventArgs instance = new SocketAsyncEventArgs(); - instance.Completed += HandleIoCompleted; - - return instance; - } - - /// <inheritdoc /> - protected override void DestroyStateObject(SocketAsyncEventArgs instance) - { - instance.Completed -= HandleIoCompleted; - instance.Dispose(); - } - - /// <inheritdoc /> - protected override void ResetStateObject(ref SocketAsyncEventArgs instance) - { - } - /// <inheritdoc /> public override int Read(ref EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) { @@ -126,8 +39,7 @@ namespace NetSharp.Raw.Datagram { throw new ArgumentException( string.Format(Resources.Culture, Resources.RawDatagramNetworkReaderRentedBufferSizeError, totalBytes, datagramSize), - nameof(readBuffer) - ); + nameof(readBuffer)); } byte[] transmissionBuffer = BufferPool.Rent(datagramSize); @@ -148,8 +60,7 @@ namespace NetSharp.Raw.Datagram { throw new ArgumentException( string.Format(Resources.Culture, Resources.RawDatagramNetworkReaderRentedBufferSizeError, totalBytes, datagramSize), - nameof(readBuffer) - ); + nameof(readBuffer)); } TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); @@ -188,8 +99,7 @@ namespace NetSharp.Raw.Datagram { throw new ArgumentException( string.Format(Resources.Culture, Resources.RawDatagramNetworkReaderRentedBufferSizeError, totalBytes, datagramSize), - nameof(writeBuffer) - ); + nameof(writeBuffer)); } byte[] transmissionBuffer = BufferPool.Rent(datagramSize); @@ -210,8 +120,7 @@ namespace NetSharp.Raw.Datagram { throw new ArgumentException( string.Format(Resources.Culture, Resources.RawDatagramNetworkReaderRentedBufferSizeError, totalBytes, datagramSize), - nameof(writeBuffer) - ); + nameof(writeBuffer)); } TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); @@ -241,9 +150,102 @@ namespace NetSharp.Raw.Datagram return new ValueTask<int>(result); } + /// <inheritdoc /> + protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) + { + return true; + } + + /// <inheritdoc /> + protected override SocketAsyncEventArgs CreateStateObject() + { + SocketAsyncEventArgs instance = new SocketAsyncEventArgs(); + instance.Completed += HandleIoCompleted; + + return instance; + } + + /// <inheritdoc /> + protected override void DestroyStateObject(SocketAsyncEventArgs instance) + { + instance.Completed -= HandleIoCompleted; + instance.Dispose(); + } + + /// <inheritdoc /> + protected override void ResetStateObject(ref SocketAsyncEventArgs instance) + { + } + + private void CompleteReceiveFrom(SocketAsyncEventArgs args) + { + PacketReadToken token = (PacketReadToken)args.UserToken; + + byte[] receiveBuffer = args.Buffer; + + switch (args.SocketError) + { + case SocketError.Success: + receiveBuffer.CopyTo(token.UserBuffer); + token.CompletionSource.SetResult(args.BytesTransferred); + break; + + case SocketError.OperationAborted: + token.CompletionSource.SetCanceled(); + break; + + default: + token.CompletionSource.SetException(new SocketException((int)args.SocketError)); + break; + } + + BufferPool.Return(receiveBuffer, true); + ArgsPool.Return(args); + } + + private void CompleteSendTo(SocketAsyncEventArgs args) + { + PacketWriteToken token = (PacketWriteToken)args.UserToken; + + byte[] sendBuffer = args.Buffer; + + switch (args.SocketError) + { + case SocketError.Success: + token.CompletionSource.SetResult(args.BytesTransferred); + break; + + case SocketError.OperationAborted: + token.CompletionSource.SetCanceled(); + break; + + default: + token.CompletionSource.SetException(new SocketException((int)args.SocketError)); + break; + } + + BufferPool.Return(sendBuffer, true); + ArgsPool.Return(args); + } + + private void HandleIoCompleted(object sender, SocketAsyncEventArgs args) + { + switch (args.LastOperation) + { + case SocketAsyncOperation.SendTo: + CompleteSendTo(args); + break; + + case SocketAsyncOperation.ReceiveFrom: + CompleteReceiveFrom(args); + break; + } + } + private readonly struct PacketReadToken { public readonly TaskCompletionSource<int> CompletionSource; + public readonly Memory<byte> UserBuffer; public PacketReadToken(TaskCompletionSource<int> completionSource, in Memory<byte> userBuffer) @@ -264,4 +266,4 @@ namespace NetSharp.Raw.Datagram } } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/RawNetworkConnectionBase.cs b/NetSharp/NetSharp/Raw/RawNetworkConnectionBase.cs @@ -13,33 +13,33 @@ namespace NetSharp.Raw /// </summary> public abstract class RawNetworkConnectionBase : IDisposable { - private readonly SlimObjectPool<SocketAsyncEventArgs> argsPool; - - private readonly ArrayPool<byte> bufferPool; - - private readonly Socket connection; - - private readonly EndPoint defaultEndPoint; - /// <summary> /// The maximum size of a pooled buffer that can be used with the <see cref="ArrayPool{T}.Shared" /> property, before a new custom pool must - /// be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs + /// be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs. /// </summary> protected const int DefaultMaxPooledBufferSize = 1024 * 1024; /// <summary> /// The maximum number of pooled buffers per bucket that can be used with the <see cref="ArrayPool{T}.Shared" /> property, before a new custom - /// pool must be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs + /// pool must be created. Taken from: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs. /// </summary> protected const int DefaultMaxPooledBuffersPerBucket = 50; /// <summary> /// The maximum size that a user supplied data buffer can be to fit into a UDP datagram. /// </summary> - protected const int MaxDatagramSize = ushort.MaxValue - 28; // 65535 - 28 = 65507 + protected const int MaxDatagramSize = ushort.MaxValue - 28; // 65535 - 28 = 65507 + + private readonly SlimObjectPool<SocketAsyncEventArgs> argsPool; + + private readonly ArrayPool<byte> bufferPool; + + private readonly Socket connection; + + private readonly EndPoint defaultEndPoint; /// <summary> - /// Constructs a new instance of the <see cref="RawNetworkConnectionBase" /> class. + /// Initialises a new instance of the <see cref="RawNetworkConnectionBase"/> class. /// </summary> /// <param name="rawConnection"> /// The underlying <see cref="Socket" /> to use for the connection. @@ -56,8 +56,12 @@ namespace NetSharp.Raw /// <param name="preallocatedStateObjects"> /// The number of state objects to preallocate. /// </param> - protected RawNetworkConnectionBase(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledBufferSize, - int pooledBuffersPerBucket = 50, uint preallocatedStateObjects = 0) + protected RawNetworkConnectionBase( + ref Socket rawConnection, + EndPoint defaultEndPoint, + int maxPooledBufferSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) { connection = rawConnection; @@ -84,7 +88,7 @@ namespace NetSharp.Raw protected ref readonly SlimObjectPool<SocketAsyncEventArgs> ArgsPool => ref argsPool; /// <summary> - /// The object pool to use to pool byte buffer instance + /// The object pool to use to pool byte buffer instance. /// </summary> protected ref readonly ArrayPool<byte> BufferPool => ref bufferPool; @@ -98,6 +102,13 @@ namespace NetSharp.Raw /// </summary> protected ref readonly EndPoint DefaultEndPoint => ref defaultEndPoint; + /// <inheritdoc /> + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + /// <inheritdoc cref="SlimObjectPool{T}.CanReuseObjectPredicate" /> protected abstract bool CanReuseStateObject(ref SocketAsyncEventArgs instance); @@ -131,6 +142,9 @@ namespace NetSharp.Raw /// <summary> /// Allows for inheritors to dispose of their own resources. /// </summary> + /// <param name="disposing"> + /// Whether the <see cref="Dispose()"/> method is being called. + /// </param> protected virtual void Dispose(bool disposing) { if (!disposing) @@ -143,12 +157,5 @@ namespace NetSharp.Raw /// <inheritdoc cref="SlimObjectPool{T}.ResetObjectDelegate" /> protected abstract void ResetStateObject(ref SocketAsyncEventArgs instance); - - /// <inheritdoc /> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/RawNetworkReaderBase.cs b/NetSharp/NetSharp/Raw/RawNetworkReaderBase.cs @@ -12,11 +12,17 @@ namespace NetSharp.Raw public abstract class RawNetworkReaderBase : RawNetworkConnectionBase, IRawNetworkReader { private readonly CancellationToken shutdownToken; + private readonly CancellationTokenSource shutdownTokenSource; - /// <inheritdoc /> - private protected RawNetworkReaderBase(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledBufferSize, int pooledBuffersPerBucket = 50, - uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, maxPooledBufferSize, pooledBuffersPerBucket, preallocatedStateObjects) + /// <inheritdoc cref="RawNetworkConnectionBase(ref Socket, EndPoint, int, int, uint)"/> + private protected RawNetworkReaderBase( + ref Socket rawConnection, + EndPoint defaultEndPoint, + int maxPooledBufferSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) + : base(ref rawConnection, defaultEndPoint, maxPooledBufferSize, pooledBuffersPerBucket, preallocatedStateObjects) { shutdownTokenSource = new CancellationTokenSource(); shutdownToken = shutdownTokenSource.Token; @@ -28,6 +34,15 @@ namespace NetSharp.Raw protected ref readonly CancellationToken ShutdownToken => ref shutdownToken; /// <inheritdoc /> + public void Shutdown() + { + shutdownTokenSource.Cancel(); + } + + /// <inheritdoc /> + public abstract void Start(ushort concurrentReadTasks); + + /// <inheritdoc /> protected override void Dispose(bool disposing) { if (!disposing) @@ -40,14 +55,5 @@ namespace NetSharp.Raw base.Dispose(disposing); } - - /// <inheritdoc /> - public void Shutdown() - { - shutdownTokenSource.Cancel(); - } - - /// <inheritdoc /> - public abstract void Start(ushort concurrentReadTasks); } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/RawNetworkWriterBase.cs b/NetSharp/NetSharp/Raw/RawNetworkWriterBase.cs @@ -12,26 +12,27 @@ namespace NetSharp.Raw /// </summary> public abstract class RawNetworkWriterBase : RawNetworkConnectionBase, IRawNetworkWriter { - /// <inheritdoc /> - protected RawNetworkWriterBase(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledBufferSize = DefaultMaxPooledBufferSize, int pooledBuffersPerBucket = 50, - uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, maxPooledBufferSize, pooledBuffersPerBucket, preallocatedStateObjects) + /// <inheritdoc cref="RawNetworkConnectionBase(ref Socket, EndPoint, int, int, uint)"/> + protected RawNetworkWriterBase( + ref Socket rawConnection, + EndPoint defaultEndPoint, + int maxPooledBufferSize = DefaultMaxPooledBufferSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) + : base(ref rawConnection, defaultEndPoint, maxPooledBufferSize, pooledBuffersPerBucket, preallocatedStateObjects) { } /// <inheritdoc /> - public abstract int Read(ref EndPoint remoteEndPoint, Memory<byte> readBuffer, - SocketFlags flags = SocketFlags.None); + public abstract int Read(ref EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None); /// <inheritdoc /> - public abstract ValueTask<int> ReadAsync(EndPoint remoteEndPoint, Memory<byte> readBuffer, - SocketFlags flags = SocketFlags.None); + public abstract ValueTask<int> ReadAsync(EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None); /// <inheritdoc /> - public abstract int Write(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, - SocketFlags flags = SocketFlags.None); + public abstract int Write(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None); /// <inheritdoc /> - public abstract ValueTask<int> WriteAsync(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, - SocketFlags flags = SocketFlags.None); + public abstract ValueTask<int> WriteAsync(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None); } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs @@ -23,7 +23,10 @@ namespace NetSharp.Raw.Stream /// Whether there exists a response to be sent back to the remote endpoint. /// </returns> // TODO implement this in a better, more robust and extensible way - public delegate bool RawStreamRequestHandler(EndPoint remoteEndPoint, in ReadOnlyMemory<byte> requestBuffer, int receivedRequestBytes, + public delegate bool RawStreamRequestHandler( + EndPoint remoteEndPoint, + in ReadOnlyMemory<byte> requestBuffer, + int receivedRequestBytes, in Memory<byte> responseBuffer); /// <summary> @@ -31,22 +34,67 @@ namespace NetSharp.Raw.Stream /// </summary> public sealed class RawStreamNetworkReader : RawNetworkReaderBase { - private readonly RawStreamRequestHandler RequestHandler; - - /// <inheritdoc /> - public RawStreamNetworkReader(ref Socket rawConnection, RawStreamRequestHandler? requestHandler, EndPoint defaultEndPoint, int maxPooledMessageSize, - int pooledBuffersPerBucket = 50, uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, maxPooledMessageSize, - pooledBuffersPerBucket, preallocatedStateObjects) + private readonly RawStreamRequestHandler requestHandler; + + /// <inheritdoc cref="RawNetworkReaderBase(ref Socket, EndPoint, int, int, uint)"/> + public RawStreamNetworkReader( + ref Socket rawConnection, + RawStreamRequestHandler? requestHandler, + EndPoint defaultEndPoint, + int maxPooledMessageSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) + : base(ref rawConnection, defaultEndPoint, maxPooledMessageSize, pooledBuffersPerBucket, preallocatedStateObjects) { if (maxPooledMessageSize <= 0) { throw new ArgumentOutOfRangeException(nameof(maxPooledMessageSize), maxPooledMessageSize, Properties.Resources.RawStreamMessageSizeUnderflow); } - RequestHandler = requestHandler ?? DefaultRequestHandler; + this.requestHandler = requestHandler ?? DefaultRequestHandler; + } + + /// <inheritdoc /> + public override void Start(ushort concurrentReadTasks) + { + for (ushort i = 0; i < concurrentReadTasks; i++) + { + StartDefaultAccept(); + } + } + + /// <inheritdoc /> + protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) + { + return true; + } + + /// <inheritdoc /> + protected override SocketAsyncEventArgs CreateStateObject() + { + SocketAsyncEventArgs args = new SocketAsyncEventArgs(); + args.Completed += HandleIoCompleted; + + return args; + } + + /// <inheritdoc /> + protected override void DestroyStateObject(SocketAsyncEventArgs instance) + { + instance.Completed -= HandleIoCompleted; + instance.Dispose(); + } + + /// <inheritdoc /> + protected override void ResetStateObject(ref SocketAsyncEventArgs instance) + { + instance.AcceptSocket = null; } - private static bool DefaultRequestHandler(EndPoint remoteEndPoint, in ReadOnlyMemory<byte> requestBuffer, int receivedRequestBytes, + private static bool DefaultRequestHandler( + EndPoint remoteEndPoint, + in ReadOnlyMemory<byte> requestBuffer, + int receivedRequestBytes, in Memory<byte> responseBuffer) { return requestBuffer.TryCopyTo(responseBuffer); @@ -89,7 +137,7 @@ namespace NetSharp.Raw.Stream private void CompleteReceive(SocketAsyncEventArgs args) { - PacketReadToken readToken = (PacketReadToken) args.UserToken; + PacketReadToken readToken = (PacketReadToken)args.UserToken; bool receivingHeader = readToken.BytesToTransfer == RawStreamPacketHeader.TotalSize; @@ -106,6 +154,7 @@ namespace NetSharp.Raw.Stream CompleteReceiveData(args, in readToken); break; } + break; default: @@ -123,8 +172,9 @@ namespace NetSharp.Raw.Stream totalReceivedBytes = previousReceivedBytes + receivedBytes, expectedBytes = readToken.BytesToTransfer; - if (totalReceivedBytes == expectedBytes) // transmission complete + if (totalReceivedBytes == expectedBytes) { + // transmission complete EndPoint clientEndPoint = args.AcceptSocket.RemoteEndPoint; // TODO use user-supplied delegate to generate response packet header @@ -136,7 +186,7 @@ namespace NetSharp.Raw.Stream Memory<byte> responseBufferMemory = responseBuffer.AsMemory(RawStreamPacketHeader.TotalSize, responseHeader.DataSize); // TODO rework request handler - bool responseExists = RequestHandler(clientEndPoint, dataBuffer, totalReceivedBytes, responseBufferMemory); + bool responseExists = requestHandler(clientEndPoint, dataBuffer, totalReceivedBytes, responseBufferMemory); switch (responseExists) { @@ -155,14 +205,16 @@ namespace NetSharp.Raw.Stream break; } } - else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete + else if (totalReceivedBytes > 0 && totalReceivedBytes < expectedBytes) { + // transmission not complete args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); StartOrContinueReceive(args); } - else if (receivedBytes == 0) // connection is dead + else if (receivedBytes == 0) { + // connection is dead CloseClientConnection(args); } } @@ -176,28 +228,31 @@ namespace NetSharp.Raw.Stream totalReceivedBytes = previousReceivedBytes + receivedBytes, expectedBytes = readToken.BytesToTransfer; - if (totalReceivedBytes == expectedBytes) // transmission complete + if (totalReceivedBytes == expectedBytes) { + // transmission complete RawStreamPacketHeader header = RawStreamPacketHeader.Deserialise(in headerBuffer); ConfigureAsyncReceiveData(args, in header); StartOrContinueReceive(args); } - else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete + else if (totalReceivedBytes > 0 && totalReceivedBytes < expectedBytes) { + // transmission not complete args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); StartOrContinueReceive(args); } - else if (receivedBytes == 0) // connection is dead + else if (receivedBytes == 0) { + // connection is dead CloseClientConnection(args); } } private void CompleteSend(SocketAsyncEventArgs args) { - PacketWriteToken writeToken = (PacketWriteToken) args.UserToken; + PacketWriteToken writeToken = (PacketWriteToken)args.UserToken; int sentBytes = args.BytesTransferred, previousSentBytes = args.Offset, @@ -207,21 +262,25 @@ namespace NetSharp.Raw.Stream switch (args.SocketError) { case SocketError.Success: - if (totalSentBytes == expectedBytes) // transmission complete + if (totalSentBytes == expectedBytes) { + // transmission complete ConfigureAsyncReceiveHeader(args); StartOrContinueReceive(args); } - else if (0 < totalSentBytes && totalSentBytes < expectedBytes) // transmission not complete + else if (totalSentBytes > 0 && totalSentBytes < expectedBytes) { + // transmission not complete args.SetBuffer(totalSentBytes, expectedBytes - totalSentBytes); StartOrContinueSend(args); } - else if (sentBytes == 0) // connection is dead + else if (sentBytes == 0) { + // connection is dead CloseClientConnection(args); } + break; default: @@ -250,7 +309,10 @@ namespace NetSharp.Raw.Stream args.UserToken = new PacketReadToken(RawStreamPacketHeader.TotalSize, null); } - private void ConfigureAsyncSendPacket(SocketAsyncEventArgs args, ref byte[] pendingPacketBuffer, in RawStreamPacketHeader pendingPacketHeader, + private void ConfigureAsyncSendPacket( + SocketAsyncEventArgs args, + ref byte[] pendingPacketBuffer, + in RawStreamPacketHeader pendingPacketHeader, in ReadOnlyMemory<byte> pendingPacketData) { BufferPool.Return(args.Buffer, true); // return and clear the requestDataBuffer (as it was already parsed) @@ -323,46 +385,10 @@ namespace NetSharp.Raw.Stream CompleteSend(args); } - /// <inheritdoc /> - protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) - { - return true; - } - - /// <inheritdoc /> - protected override SocketAsyncEventArgs CreateStateObject() - { - SocketAsyncEventArgs args = new SocketAsyncEventArgs(); - args.Completed += HandleIoCompleted; - - return args; - } - - /// <inheritdoc /> - protected override void DestroyStateObject(SocketAsyncEventArgs instance) - { - instance.Completed -= HandleIoCompleted; - instance.Dispose(); - } - - /// <inheritdoc /> - protected override void ResetStateObject(ref SocketAsyncEventArgs instance) - { - instance.AcceptSocket = null; - } - - /// <inheritdoc /> - public override void Start(ushort concurrentReadTasks) - { - for (ushort i = 0; i < concurrentReadTasks; i++) - { - StartDefaultAccept(); - } - } - private readonly struct PacketReadToken { public readonly int BytesToTransfer; + public readonly RawStreamPacketHeader? Header; public PacketReadToken(int bytesToTransfer, in RawStreamPacketHeader? header) @@ -383,4 +409,4 @@ namespace NetSharp.Raw.Stream } } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs @@ -10,9 +10,14 @@ namespace NetSharp.Raw.Stream /// </summary> public sealed class RawStreamNetworkWriter : RawNetworkWriterBase { - /// <inheritdoc /> - public RawStreamNetworkWriter(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledMessageSize = DefaultMaxPooledBufferSize, int pooledBuffersPerBucket = 50, - uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, maxPooledMessageSize, pooledBuffersPerBucket, preallocatedStateObjects) + /// <inheritdoc cref="RawNetworkWriterBase(ref Socket, EndPoint, int, int, uint)" /> + public RawStreamNetworkWriter( + ref Socket rawConnection, + EndPoint defaultEndPoint, + int maxPooledMessageSize = DefaultMaxPooledBufferSize, + int pooledBuffersPerBucket = 50, + uint preallocatedStateObjects = 0) + : base(ref rawConnection, defaultEndPoint, maxPooledMessageSize, pooledBuffersPerBucket, preallocatedStateObjects) { if (maxPooledMessageSize <= 0) { @@ -20,8 +25,136 @@ namespace NetSharp.Raw.Stream } } - private static void ConfigureAsyncSendPacket(SocketAsyncEventArgs args, ref byte[] pendingPacketBuffer, in RawStreamPacketHeader pendingPacketHeader, - in ReadOnlyMemory<byte> userDataBuffer, TaskCompletionSource<int> tcs) + /// <inheritdoc /> + public override int Read(ref EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) + { + static int ReadBytesIntoBuffer(Socket connection, ref byte[] buffer, int count, SocketFlags flags) + { + int readBytes = 0; + + do + { + readBytes += connection.Receive(buffer, readBytes, count - readBytes, flags); + } + while (readBytes < count && readBytes > 0); + + return readBytes; + } + + byte[] pendingHeaderBuffer = BufferPool.Rent(RawStreamPacketHeader.TotalSize); + + _ = ReadBytesIntoBuffer(Connection, ref pendingHeaderBuffer, RawStreamPacketHeader.TotalSize, flags); + + RawStreamPacketHeader packetHeader = RawStreamPacketHeader.Deserialise(pendingHeaderBuffer); + BufferPool.Return(pendingHeaderBuffer, true); // return and clear the pendingHeaderBuffer (as it was already parsed) + + byte[] pendingPacketDataBuffer = BufferPool.Rent(packetHeader.DataSize); + + int bodyBytes = ReadBytesIntoBuffer(Connection, ref pendingPacketDataBuffer, packetHeader.DataSize, flags); + + pendingPacketDataBuffer.AsMemory(0, readBuffer.Length).CopyTo(readBuffer); + BufferPool.Return(pendingPacketDataBuffer, true); // return and clear the pendingDataBuffer (as it was already copied) + + return bodyBytes; // we only return the number of bytes of user data that were read + } + + /// <inheritdoc /> + public override ValueTask<int> ReadAsync(EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) + { + TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); + SocketAsyncEventArgs args = ArgsPool.Rent(); + + ConfigureAsyncReceiveHeader(args, in readBuffer, tcs); + + args.RemoteEndPoint = remoteEndPoint; + args.SocketFlags = flags; + + StartReceive(args); + + return new ValueTask<int>(tcs.Task); + } + + /// <inheritdoc /> + public override int Write(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None) + { + static int WriteBytesFromBuffer(Socket connection, ref byte[] buffer, int count, SocketFlags flags) + { + int writtenBytes = 0; + + do + { + writtenBytes += connection.Send(buffer, writtenBytes, count - writtenBytes, flags); + } + while (writtenBytes < count && writtenBytes > 0); + + return writtenBytes; + } + + RawStreamPacketHeader pendingPacketHeader = new RawStreamPacketHeader(writeBuffer.Length); + int totalPacketSize = RawStreamPacket.TotalPacketSize(in pendingPacketHeader); + byte[] pendingPacketBuffer = BufferPool.Rent(totalPacketSize); + + RawStreamPacket.Serialise(pendingPacketBuffer, in pendingPacketHeader, in writeBuffer); + + _ = WriteBytesFromBuffer(Connection, ref pendingPacketBuffer, totalPacketSize, flags); + BufferPool.Return(pendingPacketBuffer, true); // return and clear the pendingPacketBuffer (as it was already cleared) + + return pendingPacketHeader.DataSize; // we only return the number of bytes of user data that were written + } + + /// <inheritdoc /> + public override ValueTask<int> WriteAsync(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None) + { + TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); + SocketAsyncEventArgs args = ArgsPool.Rent(); + + RawStreamPacketHeader pendingPacketHeader = new RawStreamPacketHeader(writeBuffer.Length); + int totalPacketSize = RawStreamPacket.TotalPacketSize(in pendingPacketHeader); + byte[] pendingPacketBuffer = BufferPool.Rent(totalPacketSize); + + ConfigureAsyncSendPacket(args, ref pendingPacketBuffer, in pendingPacketHeader, in writeBuffer, tcs); + + args.RemoteEndPoint = remoteEndPoint; + args.SocketFlags = flags; + + StartSend(args); + + return new ValueTask<int>(tcs.Task); + } + + /// <inheritdoc /> + protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) + { + return true; + } + + /// <inheritdoc /> + protected override SocketAsyncEventArgs CreateStateObject() + { + SocketAsyncEventArgs args = new SocketAsyncEventArgs(); + args.Completed += HandleIoCompleted; + + return args; + } + + /// <inheritdoc /> + protected override void DestroyStateObject(SocketAsyncEventArgs instance) + { + instance.Completed -= HandleIoCompleted; + instance.Dispose(); + } + + /// <inheritdoc /> + protected override void ResetStateObject(ref SocketAsyncEventArgs instance) + { + } + + private static void ConfigureAsyncSendPacket( + SocketAsyncEventArgs args, + ref byte[] pendingPacketBuffer, + in RawStreamPacketHeader pendingPacketHeader, + in ReadOnlyMemory<byte> userDataBuffer, + TaskCompletionSource<int> tcs) { RawStreamPacket.Serialise(pendingPacketBuffer, in pendingPacketHeader, in userDataBuffer); @@ -32,7 +165,7 @@ namespace NetSharp.Raw.Stream private void CompleteReceive(SocketAsyncEventArgs args) { - PacketReadToken readToken = (PacketReadToken) args.UserToken; + PacketReadToken readToken = (PacketReadToken)args.UserToken; bool receivingHeader = readToken.BytesToTransfer == RawStreamPacketHeader.TotalSize; @@ -55,10 +188,11 @@ namespace NetSharp.Raw.Stream CompleteReceiveData(args, in readToken); break; } + break; default: - readToken.CompletionSource.SetException(new SocketException((int) args.SocketError)); + readToken.CompletionSource.SetException(new SocketException((int)args.SocketError)); CleanupTransmissionBufferAndState(args); break; @@ -72,8 +206,9 @@ namespace NetSharp.Raw.Stream totalReceivedBytes = previousReceivedBytes + receivedBytes, expectedBytes = readToken.BytesToTransfer; - if (totalReceivedBytes == expectedBytes) // transmission complete + if (totalReceivedBytes == expectedBytes) { + // transmission complete args.Buffer.AsMemory(0, readToken.UserDataBuffer.Length).CopyTo(readToken.UserDataBuffer); // we only return the number of bytes of user data that were read @@ -81,15 +216,17 @@ namespace NetSharp.Raw.Stream CleanupTransmissionBufferAndState(args); } - else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete + else if (totalReceivedBytes > 0 && totalReceivedBytes < expectedBytes) { + // transmission not complete args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); ContinueReceive(args); } - else if (receivedBytes == 0) // connection is dead + else if (receivedBytes == 0) { - readToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); + // connection is dead + readToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown)); CleanupTransmissionBufferAndState(args); } @@ -102,8 +239,9 @@ namespace NetSharp.Raw.Stream totalReceivedBytes = previousReceivedBytes + receivedBytes, expectedBytes = readToken.BytesToTransfer; - if (totalReceivedBytes == expectedBytes) // transmission complete + if (totalReceivedBytes == expectedBytes) { + // transmission complete Memory<byte> headerBuffer = args.Buffer.AsMemory(0, RawStreamPacketHeader.TotalSize); RawStreamPacketHeader header = RawStreamPacketHeader.Deserialise(in headerBuffer); @@ -111,15 +249,17 @@ namespace NetSharp.Raw.Stream StartReceive(args); } - else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete + else if (totalReceivedBytes > 0 && totalReceivedBytes < expectedBytes) { + // transmission not complete args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); ContinueReceive(args); } - else if (receivedBytes == 0) // connection is dead + else if (receivedBytes == 0) { - readToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); + // connection is dead + readToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown)); CleanupTransmissionBufferAndState(args); } @@ -127,7 +267,7 @@ namespace NetSharp.Raw.Stream private void CompleteSend(SocketAsyncEventArgs args) { - PacketWriteToken writeToken = (PacketWriteToken) args.UserToken; + PacketWriteToken writeToken = (PacketWriteToken)args.UserToken; int sentBytes = args.BytesTransferred, previousSentBytes = args.Offset, @@ -143,36 +283,42 @@ namespace NetSharp.Raw.Stream break; case SocketError.Success: - if (totalSentBytes == expectedBytes) // transmission complete + if (totalSentBytes == expectedBytes) { - // we only return the number of bytes of user data that were written + // transmission complete we only return the number of bytes of user data that were written writeToken.CompletionSource.SetResult(totalSentBytes - RawStreamPacketHeader.TotalSize); CleanupTransmissionBufferAndState(args); } - else if (0 < totalSentBytes && totalSentBytes < expectedBytes) // transmission not complete + else if (totalSentBytes > 0 && totalSentBytes < expectedBytes) { + // transmission not complete args.SetBuffer(totalSentBytes, expectedBytes - totalSentBytes); ContinueSend(args); } - else if (sentBytes == 0) // connection is dead + else if (sentBytes == 0) { - writeToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); + // connection is dead + writeToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown)); CleanupTransmissionBufferAndState(args); } + break; default: - writeToken.CompletionSource.SetException(new SocketException((int) args.SocketError)); + writeToken.CompletionSource.SetException(new SocketException((int)args.SocketError)); CleanupTransmissionBufferAndState(args); break; } } - private void ConfigureAsyncReceiveData(SocketAsyncEventArgs args, in RawStreamPacketHeader receivedPacketHeader, in Memory<byte> userDataBuffer, + private void ConfigureAsyncReceiveData( + SocketAsyncEventArgs args, + in RawStreamPacketHeader receivedPacketHeader, + in Memory<byte> userDataBuffer, TaskCompletionSource<int> tcs) { BufferPool.Return(args.Buffer, true); // return and clear the requestHeaderBuffer (as it was already parsed) @@ -246,133 +392,14 @@ namespace NetSharp.Raw.Stream CompleteSend(args); } - /// <inheritdoc /> - protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) - { - return true; - } - - /// <inheritdoc /> - protected override SocketAsyncEventArgs CreateStateObject() - { - SocketAsyncEventArgs args = new SocketAsyncEventArgs(); - args.Completed += HandleIoCompleted; - - return args; - } - - /// <inheritdoc /> - protected override void DestroyStateObject(SocketAsyncEventArgs instance) - { - instance.Completed -= HandleIoCompleted; - instance.Dispose(); - } - - /// <inheritdoc /> - protected override void ResetStateObject(ref SocketAsyncEventArgs instance) - { - } - - /// <inheritdoc /> - public override int Read(ref EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) - { - static int ReadBytesIntoBuffer(Socket connection, ref byte[] buffer, int count, SocketFlags flags) - { - int readBytes = 0; - - do - { - readBytes += connection.Receive(buffer, readBytes, count - readBytes, flags); - } while (readBytes < count && readBytes > 0); - - return readBytes; - } - - byte[] pendingHeaderBuffer = BufferPool.Rent(RawStreamPacketHeader.TotalSize); - - int _ = ReadBytesIntoBuffer(Connection, ref pendingHeaderBuffer, RawStreamPacketHeader.TotalSize, flags); - - RawStreamPacketHeader packetHeader = RawStreamPacketHeader.Deserialise(pendingHeaderBuffer); - BufferPool.Return(pendingHeaderBuffer, true); // return and clear the pendingHeaderBuffer (as it was already parsed) - - byte[] pendingPacketDataBuffer = BufferPool.Rent(packetHeader.DataSize); - - int bodyBytes = ReadBytesIntoBuffer(Connection, ref pendingPacketDataBuffer, packetHeader.DataSize, flags); - - pendingPacketDataBuffer.AsMemory(0, readBuffer.Length).CopyTo(readBuffer); - BufferPool.Return(pendingPacketDataBuffer, true); // return and clear the pendingDataBuffer (as it was already copied) - - return bodyBytes; // we only return the number of bytes of user data that were read - } - - /// <inheritdoc /> - public override ValueTask<int> ReadAsync(EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) - { - TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); - SocketAsyncEventArgs args = ArgsPool.Rent(); - - ConfigureAsyncReceiveHeader(args, in readBuffer, tcs); - - args.RemoteEndPoint = remoteEndPoint; - args.SocketFlags = flags; - - StartReceive(args); - - return new ValueTask<int>(tcs.Task); - } - - /// <inheritdoc /> - public override int Write(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None) - { - static int WriteBytesFromBuffer(Socket connection, ref byte[] buffer, int count, SocketFlags flags) - { - int writtenBytes = 0; - - do - { - writtenBytes += connection.Send(buffer, writtenBytes, count - writtenBytes, flags); - } while (writtenBytes < count && writtenBytes > 0); - - return writtenBytes; - } - - RawStreamPacketHeader pendingPacketHeader = new RawStreamPacketHeader(writeBuffer.Length); - int totalPacketSize = RawStreamPacket.TotalPacketSize(in pendingPacketHeader); - byte[] pendingPacketBuffer = BufferPool.Rent(totalPacketSize); - - RawStreamPacket.Serialise(pendingPacketBuffer, in pendingPacketHeader, in writeBuffer); - - int _ = WriteBytesFromBuffer(Connection, ref pendingPacketBuffer, totalPacketSize, flags); - BufferPool.Return(pendingPacketBuffer, true); // return and clear the pendingPacketBuffer (as it was already cleared) - - return pendingPacketHeader.DataSize; // we only return the number of bytes of user data that were written - } - - /// <inheritdoc /> - public override ValueTask<int> WriteAsync(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None) - { - TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); - SocketAsyncEventArgs args = ArgsPool.Rent(); - - RawStreamPacketHeader pendingPacketHeader = new RawStreamPacketHeader(writeBuffer.Length); - int totalPacketSize = RawStreamPacket.TotalPacketSize(in pendingPacketHeader); - byte[] pendingPacketBuffer = BufferPool.Rent(totalPacketSize); - - ConfigureAsyncSendPacket(args, ref pendingPacketBuffer, in pendingPacketHeader, in writeBuffer, tcs); - - args.RemoteEndPoint = remoteEndPoint; - args.SocketFlags = flags; - - StartSend(args); - - return new ValueTask<int>(tcs.Task); - } - private readonly struct PacketReadToken { internal readonly int BytesToTransfer; + internal readonly TaskCompletionSource<int> CompletionSource; + internal readonly RawStreamPacketHeader? Header; + internal readonly Memory<byte> UserDataBuffer; internal PacketReadToken(int bytesToTransfer, in RawStreamPacketHeader? header, in Memory<byte> userDataBuffer, TaskCompletionSource<int> tcs) @@ -390,6 +417,7 @@ namespace NetSharp.Raw.Stream private readonly struct PacketWriteToken { internal readonly int BytesToTransfer; + internal readonly TaskCompletionSource<int> CompletionSource; internal PacketWriteToken(int bytesToTransfer, TaskCompletionSource<int> tcs) @@ -400,4 +428,4 @@ namespace NetSharp.Raw.Stream } } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamPacket.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamPacket.cs @@ -1,69 +1,9 @@ using System; using System.Runtime.CompilerServices; -using NetSharp.Utils.Conversion; - namespace NetSharp.Raw.Stream { /// <summary> - /// Holds metadata about a raw stream packet. - /// </summary> - internal readonly struct RawStreamPacketHeader - { - /// <summary> - /// The total size of the header in bytes. - /// </summary> - internal const int TotalSize = sizeof(int); - - /// <summary> - /// The size of the user supplied data segment in bytes. - /// </summary> - internal readonly int DataSize; - - /// <summary> - /// Constructs a new instance of the <see cref="RawStreamPacketHeader" /> struct. - /// </summary> - /// <param name="dataSize"> - /// The size of the user supplied data segment. - /// </param> - internal RawStreamPacketHeader(int dataSize) - { - DataSize = dataSize; - } - - /// <summary> - /// Deserialises a <see cref="RawStreamPacketHeader" /> instance from the given <paramref name="buffer" />. - /// </summary> - /// <param name="buffer"> - /// A buffer containing a serialised <see cref="RawStreamPacketHeader" /> instance. Must be at least of size <see cref="TotalSize" />. - /// </param> - /// <returns> - /// The deserialised instance. - /// </returns> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static RawStreamPacketHeader Deserialise(in Memory<byte> buffer) - { - Span<byte> serialisedDataSize = buffer.Slice(0, sizeof(int)).Span; - int dataSize = EndianAwareBitConverter.ToInt32(serialisedDataSize); - - return new RawStreamPacketHeader(dataSize); - } - - /// <summary> - /// Serialises the current <see cref="RawStreamPacketHeader" /> instance into the given <paramref name="buffer" />. - /// </summary> - /// <param name="buffer"> - /// The buffer into which to serialise the current instance. Must be at least of size <see cref="TotalSize" />. - /// </param> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void Serialise(in Memory<byte> buffer) - { - Span<byte> serialisedDataSize = EndianAwareBitConverter.GetBytes(DataSize); - serialisedDataSize.CopyTo(buffer.Slice(0, sizeof(int)).Span); - } - } - - /// <summary> /// Provides helper methods to manipulate the binary packet format used by stream network handlers. /// </summary> internal static class RawStreamPacket @@ -104,4 +44,4 @@ namespace NetSharp.Raw.Stream return RawStreamPacketHeader.TotalSize + packetHeader.DataSize; } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamPacketHeader.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamPacketHeader.cs @@ -0,0 +1,65 @@ +using System; +using System.Runtime.CompilerServices; + +using NetSharp.Utils.Conversion; + +namespace NetSharp.Raw.Stream +{ + /// <summary> + /// Holds metadata about a raw stream packet. + /// </summary> + internal readonly struct RawStreamPacketHeader + { + /// <summary> + /// The total size of the header in bytes. + /// </summary> + internal const int TotalSize = sizeof(int); + + /// <summary> + /// The size of the user supplied data segment in bytes. + /// </summary> + internal readonly int DataSize; + + /// <summary> + /// Initialises a new instance of the <see cref="RawStreamPacketHeader"/> struct. + /// </summary> + /// <param name="dataSize"> + /// The size of the user supplied data segment. + /// </param> + internal RawStreamPacketHeader(int dataSize) + { + DataSize = dataSize; + } + + /// <summary> + /// Deserialises a <see cref="RawStreamPacketHeader" /> instance from the given <paramref name="buffer" />. + /// </summary> + /// <param name="buffer"> + /// A buffer containing a serialised <see cref="RawStreamPacketHeader" /> instance. Must be at least of size <see cref="TotalSize" />. + /// </param> + /// <returns> + /// The deserialised instance. + /// </returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static RawStreamPacketHeader Deserialise(in Memory<byte> buffer) + { + Span<byte> serialisedDataSize = buffer.Slice(0, sizeof(int)).Span; + int dataSize = EndianAwareBitConverter.ToInt32(serialisedDataSize); + + return new RawStreamPacketHeader(dataSize); + } + + /// <summary> + /// Serialises the current <see cref="RawStreamPacketHeader" /> instance into the given <paramref name="buffer" />. + /// </summary> + /// <param name="buffer"> + /// The buffer into which to serialise the current instance. Must be at least of size <see cref="TotalSize" />. + /// </param> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void Serialise(in Memory<byte> buffer) + { + Span<byte> serialisedDataSize = EndianAwareBitConverter.GetBytes(DataSize); + serialisedDataSize.CopyTo(buffer.Slice(0, sizeof(int)).Span); + } + } +} diff --git a/NetSharp/NetSharp/Utils/Conversion/EndianAwareBitConverter.cs b/NetSharp/NetSharp/Utils/Conversion/EndianAwareBitConverter.cs @@ -8,20 +8,6 @@ namespace NetSharp.Utils.Conversion /// </summary> internal static class EndianAwareBitConverter { - /// <summary> - /// Reverses the given bytes if the endian-nes doesn't match. - /// </summary> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Span<byte> ReverseAsNeeded(Span<byte> bytes, bool toLittleEndian) - { - if (toLittleEndian != BitConverter.IsLittleEndian) - { - bytes.Reverse(); - } - - return bytes; - } - /// <inheritdoc cref="BitConverter.GetBytes(bool)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Span<byte> GetBytes(bool value, bool littleEndian = false) @@ -161,5 +147,19 @@ namespace NetSharp.Utils.Conversion { return BitConverter.ToUInt64(ReverseAsNeeded(bytes, littleEndian)); } + + /// <summary> + /// Reverses the given bytes if the endian-nes doesn't match. + /// </summary> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Span<byte> ReverseAsNeeded(Span<byte> bytes, bool toLittleEndian) + { + if (toLittleEndian != BitConverter.IsLittleEndian) + { + bytes.Reverse(); + } + + return bytes; + } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/Utils/SlimObjectPool.cs b/NetSharp/NetSharp/Utils/SlimObjectPool.cs @@ -13,13 +13,17 @@ namespace NetSharp.Utils public sealed class SlimObjectPool<T> : IDisposable { private readonly CanReuseObjectPredicate canObjectBeRebufferedPredicate; + private readonly CreateObjectDelegate createObjectDelegate; + private readonly DestroyObjectDelegate destroyObjectDelegate; + private readonly IProducerConsumerCollection<T> objectBuffer; + private readonly ResetObjectDelegate resetObjectDelegate; /// <summary> - /// Constructs a new instance of the <see cref="SlimObjectPool{T}" /> class. + /// Initialises a new instance of the <see cref="SlimObjectPool{T}"/> class. /// </summary> /// <param name="createDelegate"> /// The delegate method to use to create new pooled object instances. @@ -33,12 +37,11 @@ namespace NetSharp.Utils /// <param name="rebufferPredicate"> /// The delegate method to use to decide whether an instance can be reused. /// </param> - /// <param name="baseCollection"> - /// The underlying pooled object buffer to use. - /// </param> - public SlimObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, - in DestroyObjectDelegate destroyDelegate, in CanReuseObjectPredicate rebufferPredicate, - in IProducerConsumerCollection<T> baseCollection) + public SlimObjectPool( + CreateObjectDelegate createDelegate, + ResetObjectDelegate resetDelegate, + DestroyObjectDelegate destroyDelegate, + CanReuseObjectPredicate rebufferPredicate) { createObjectDelegate = createDelegate; @@ -48,28 +51,7 @@ namespace NetSharp.Utils canObjectBeRebufferedPredicate = rebufferPredicate; - objectBuffer = baseCollection; - } - - /// <summary> - /// Constructs a new instance of the <see cref="SlimObjectPool{T}" /> class. - /// </summary> - /// <param name="createDelegate"> - /// The delegate method to use to create new pooled object instances. - /// </param> - /// <param name="resetDelegate"> - /// The delegate method to use to reset used pooled object instances. - /// </param> - /// <param name="destroyDelegate"> - /// The delegate method to use to destroy pooled object instances that cannot be reused. - /// </param> - /// <param name="rebufferPredicate"> - /// The delegate method to use to decide whether an instance can be reused. - /// </param> - public SlimObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, - in DestroyObjectDelegate destroyDelegate, in CanReuseObjectPredicate rebufferPredicate) - : this(in createDelegate, in resetDelegate, in destroyDelegate, in rebufferPredicate, new ConcurrentBag<T>()) - { + objectBuffer = new ConcurrentBag<T>(); } /// <summary> @@ -146,12 +128,12 @@ namespace NetSharp.Utils objectBuffer.TryAdd(instance); - //bool couldRebuffer = false; + // bool couldRebuffer = false; - //while (!couldRebuffer) - //{ + // while (!couldRebuffer) + // { // couldRebuffer = objectBuffer.TryAdd(instance); - //} + // } } else { @@ -159,4 +141,4 @@ namespace NetSharp.Utils } } } -} -\ No newline at end of file +} diff --git a/NetSharp/NetSharp/stylecop.json b/NetSharp/NetSharp/stylecop.json @@ -0,0 +1,60 @@ +{ + "settings": { + "documentationRules": { + "companyName": "", + "copyrightText": "", + "documentationCulture": "en-GB", + "documentExposedElements": true, + "documentInterfaces": true, + "documentInternalElements": false, + "documentPrivateElements": false, + "documentPrivateFields": false, + "excludeFromPunctuationCheck": [ + "seealso" + ], + "fileNamingConvention": "stylecop", + "headerDecoration": "", + "variables": {}, + "xmlHeader": true + }, + "indentation": { + "indentationSize": 4, + "tabSize": 4, + "useTabs": false + }, + "layoutRules": { + "allowConsecutiveUsings": true, + "newlineAtEndOfFile": "require" + }, + "maintainabilityRules": { + "topLevelTypes": [ + "class" + ] + }, + "namingRules": { + "allowCommonHungarianPrefixes": true, + "allowedHungarianPrefixes": [], + "allowedNamespaceComponents": [], + "includeInferredTupleElementNames": false, + "tupleElementNameCasing": "PascalCase" + }, + "orderingRules": { + "blankLinesBetweenUsingGroups": "require", + "elementOrder": [ + "kind", + "accessibility", + "constant", + "static", + "readonly" + ], + "systemUsingDirectivesFirst": true, + "usingDirectivesPlacement": "outsideNamespace" + }, + "readabilityRules": { + "allowBuiltInTypeAliases": false + }, + "spacingRules": { + + } + } +}