NetSharp

NetSharp.git
git clone git://git.lenczewski.org/NetSharp.git
Log | Files | Refs | README | LICENSE

commit 7a8b5e7d9358e4ce23fc70dee43163f037ec8a65
parent 40e536d269edc0d5f22c0de8ae154abc4b324ecf
Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com>
Date:   Thu, 11 Jun 2020 18:43:36 +0100

Removed stale files, and internalised certain parts of the project.

Diffstat:
MNetSharp/NetSharp/NetSharp.csproj | 6+++---
ANetSharp/NetSharp/Packets/RawStreamPacket.cs | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DNetSharp/NetSharp/Raw/IRawNetworkTransportProvider.cs | 72------------------------------------------------------------------------
MNetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs | 2++
MNetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs | 139++++++++++++++++++++++++++++++++++++++++---------------------------------------
DNetSharp/NetSharp/Raw/Stream/RawStreamPacket.cs | 63---------------------------------------------------------------
DNetSharp/NetSharp/Raw/Stream/VariablePacketRawStreamNetworkWriter.cs | 360-------------------------------------------------------------------------------
DNetSharp/NetSharp/Utils/BiDictionary.cs | 276-------------------------------------------------------------------------------
MNetSharp/NetSharp/Utils/Conversion/EndianAwareBitConverter.cs | 42+++++++++++++++++++++---------------------
MNetSharp/NetSharp/Utils/SlimObjectPool.cs | 36++++++++++++++++++------------------
DNetSharp/NetSharp/Utils/TransmissionResult.cs | 78------------------------------------------------------------------------------
MNetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkReaderBenchmark.cs | 11++++-------
MNetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkWriterAsyncBenchmark.cs | 10++++------
MNetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkWriterSyncBenchmark.cs | 10++++------
MNetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkReaderBenchmark.cs | 12+++++-------
MNetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkWriterAsyncBenchmark.cs | 11+++++------
MNetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkWriterSyncBenchmark.cs | 11+++++------
MNetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkReaderExample.cs | 5++---
MNetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterAsyncExample.cs | 40+++++++++++++++++++++++-----------------
MNetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterSyncExample.cs | 40+++++++++++++++++++++++-----------------
MNetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/RawStreamChatServer.cs | 8+++-----
MNetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkReaderExample.cs | 5++---
MNetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterAsyncExample.cs | 9+++++----
MNetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterSyncExample.cs | 9+++++----
24 files changed, 260 insertions(+), 1051 deletions(-)

diff --git a/NetSharp/NetSharp/NetSharp.csproj b/NetSharp/NetSharp/NetSharp.csproj @@ -31,12 +31,12 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> - <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="3.1.5" /> + <None Remove="Utils\Conversion\EndianAwareBitConverter.cs~RF33e825.TMP" /> </ItemGroup> <ItemGroup> - <Folder Include="Packets\" /> + <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> + <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="3.1.5" /> </ItemGroup> <ItemGroup> diff --git a/NetSharp/NetSharp/Packets/RawStreamPacket.cs b/NetSharp/NetSharp/Packets/RawStreamPacket.cs @@ -0,0 +1,55 @@ +using System; +using System.Runtime.CompilerServices; + +using NetSharp.Utils.Conversion; + +namespace NetSharp.Packets +{ + internal readonly struct RawStreamPacket + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Serialise(in Memory<byte> buffer, in RawStreamPacketHeader packetHeader, in ReadOnlyMemory<byte> packetData) + { + packetHeader.Serialise(buffer.Slice(0, RawStreamPacketHeader.TotalSize)); + + packetData.CopyTo(buffer.Slice(RawStreamPacketHeader.TotalSize, packetData.Length)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int TotalPacketSize(in RawStreamPacketHeader packetHeader) + { + return RawStreamPacketHeader.TotalSize + packetHeader.DataSize; + } + } + + internal readonly struct RawStreamPacketHeader + { + internal const int TotalSize = sizeof(int); + + internal readonly int DataSize; + + internal RawStreamPacketHeader(int dataSize) + { + DataSize = dataSize; + } + + 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); + } + + internal void Serialise(in Memory<byte> buffer) + { + Span<byte> serialisedDataSize = EndianAwareBitConverter.GetBytes(DataSize); + serialisedDataSize.CopyTo(buffer.Slice(0, sizeof(int)).Span); + } + + public override string ToString() + { + return $"[Data Segment Size: {DataSize}]"; + } + } +} +\ No newline at end of file diff --git a/NetSharp/NetSharp/Raw/IRawNetworkTransportProvider.cs b/NetSharp/NetSharp/Raw/IRawNetworkTransportProvider.cs @@ -1,71 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; - -using NetSharp.Raw.Datagram; -using NetSharp.Raw.Stream; - -namespace NetSharp.Raw -{ - public interface IRawNetworkTransportProvider<in TReqHandler> where TReqHandler : Delegate - { - SocketType TransportProtocolType { get; } - - RawNetworkReaderBase GetReader(ref Socket rawConnection, EndPoint defaultEndPoint, TReqHandler requestHandler, int maxPooledBufferSize, - int maxPooledBuffersPerBucket = 1000, uint preallocatedStateObjects = 0); - - RawNetworkWriterBase GetWriter(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledBufferSize, int maxPooledBuffersPerBucket = 1000, - uint preallocatedStateObjects = 0); - } - - public sealed class RawDatagramNetworkTransportProvider : IRawNetworkTransportProvider<RawDatagramRequestHandler> - { - private readonly ushort datagramSize; - - public RawDatagramNetworkTransportProvider(ushort datagramSize) - { - this.datagramSize = datagramSize; - } - - /// <inheritdoc /> - public SocketType TransportProtocolType { get; } = SocketType.Dgram; - - /// <inheritdoc /> - public RawNetworkReaderBase GetReader(ref Socket rawConnection, EndPoint defaultEndPoint, RawDatagramRequestHandler? requestHandler, - int maxPooledBufferSize, int maxPooledBuffersPerBucket = 1000, uint preallocatedStateObjects = 0) - { - return new RawDatagramNetworkReader(ref rawConnection, requestHandler, defaultEndPoint, maxPooledBufferSize, - maxPooledBuffersPerBucket, preallocatedStateObjects); - } - - /// <inheritdoc /> - public RawNetworkWriterBase GetWriter(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledBufferSize, - int maxPooledBuffersPerBucket = 1000, uint preallocatedStateObjects = 0) - { - return new RawDatagramNetworkWriter(ref rawConnection, defaultEndPoint, maxPooledBufferSize, - maxPooledBuffersPerBucket, preallocatedStateObjects); - } - } - - public sealed class RawStreamNetworkTransportProvider : IRawNetworkTransportProvider<RawStreamRequestHandler> - { - /// <inheritdoc /> - public SocketType TransportProtocolType { get; } = SocketType.Stream; - - /// <inheritdoc /> - public RawNetworkReaderBase GetReader(ref Socket rawConnection, EndPoint defaultEndPoint, RawStreamRequestHandler? requestHandler, - int maxPooledBufferSize, int maxPooledBuffersPerBucket = 1000, uint preallocatedStateObjects = 0) - { - return new RawStreamNetworkReader(ref rawConnection, requestHandler, defaultEndPoint, maxPooledBufferSize, - maxPooledBuffersPerBucket, preallocatedStateObjects); - } - - /// <inheritdoc /> - public RawNetworkWriterBase GetWriter(ref Socket rawConnection, EndPoint defaultEndPoint, int maxPooledBufferSize, - int maxPooledBuffersPerBucket = 1000, uint preallocatedStateObjects = 0) - { - return new RawStreamNetworkWriter(ref rawConnection, defaultEndPoint, maxPooledBufferSize, - maxPooledBuffersPerBucket, preallocatedStateObjects); - } - } -} -\ No newline at end of file diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs @@ -2,6 +2,8 @@ using System.Net; using System.Net.Sockets; +using NetSharp.Packets; + namespace NetSharp.Raw.Stream { public delegate bool RawStreamRequestHandler(EndPoint remoteEndPoint, in ReadOnlyMemory<byte> requestBuffer, int receivedRequestBytes, diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs @@ -3,9 +3,10 @@ using System.Net; using System.Net.Sockets; using System.Threading.Tasks; +using NetSharp.Packets; + namespace NetSharp.Raw.Stream { - // TODO finish off implementation public sealed class RawStreamNetworkWriter : RawNetworkWriterBase { /// <inheritdoc /> @@ -23,66 +24,6 @@ namespace NetSharp.Raw.Stream { PacketReadToken readToken = (PacketReadToken) args.UserToken; - void CompleteReceiveHeader(SocketAsyncEventArgs args, in PacketReadToken readToken) - { - int receivedBytes = args.BytesTransferred, - previousReceivedBytes = args.Offset, - totalReceivedBytes = previousReceivedBytes + receivedBytes, - expectedBytes = readToken.BytesToTransfer; - - if (totalReceivedBytes == expectedBytes) // transmission complete - { - Memory<byte> headerBuffer = args.Buffer.AsMemory(0, RawStreamPacketHeader.TotalSize); - RawStreamPacketHeader header = RawStreamPacketHeader.Deserialise(in headerBuffer); - - ConfigureAsyncReceiveData(args, in header, in readToken.UserDataBuffer, readToken.CompletionSource); - - StartReceive(args); - } - else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete - { - args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); - - ContinueReceive(args); - } - else if (receivedBytes == 0) // connection is dead - { - readToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); - - CleanupTransmissionBufferAndState(args); - } - } - - void CompleteReceiveData(SocketAsyncEventArgs args, in PacketReadToken readToken) - { - int receivedBytes = args.BytesTransferred, - previousReceivedBytes = args.Offset, - totalReceivedBytes = previousReceivedBytes + receivedBytes, - expectedBytes = readToken.BytesToTransfer; - - 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 - readToken.CompletionSource.SetResult(totalReceivedBytes); - - CleanupTransmissionBufferAndState(args); - } - else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete - { - args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); - - ContinueReceive(args); - } - else if (receivedBytes == 0) // connection is dead - { - readToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); - - CleanupTransmissionBufferAndState(args); - } - } - bool receivingHeader = readToken.BytesToTransfer == RawStreamPacketHeader.TotalSize; switch (args.SocketError) @@ -114,6 +55,66 @@ namespace NetSharp.Raw.Stream } } + private void CompleteReceiveData(SocketAsyncEventArgs args, in PacketReadToken readToken) + { + int receivedBytes = args.BytesTransferred, + previousReceivedBytes = args.Offset, + totalReceivedBytes = previousReceivedBytes + receivedBytes, + expectedBytes = readToken.BytesToTransfer; + + 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 + readToken.CompletionSource.SetResult(totalReceivedBytes); + + CleanupTransmissionBufferAndState(args); + } + else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete + { + args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); + + ContinueReceive(args); + } + else if (receivedBytes == 0) // connection is dead + { + readToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); + + CleanupTransmissionBufferAndState(args); + } + } + + private void CompleteReceiveHeader(SocketAsyncEventArgs args, in PacketReadToken readToken) + { + int receivedBytes = args.BytesTransferred, + previousReceivedBytes = args.Offset, + totalReceivedBytes = previousReceivedBytes + receivedBytes, + expectedBytes = readToken.BytesToTransfer; + + if (totalReceivedBytes == expectedBytes) // transmission complete + { + Memory<byte> headerBuffer = args.Buffer.AsMemory(0, RawStreamPacketHeader.TotalSize); + RawStreamPacketHeader header = RawStreamPacketHeader.Deserialise(in headerBuffer); + + ConfigureAsyncReceiveData(args, in header, in readToken.UserDataBuffer, readToken.CompletionSource); + + StartReceive(args); + } + else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete + { + args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); + + ContinueReceive(args); + } + else if (receivedBytes == 0) // connection is dead + { + readToken.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); + + CleanupTransmissionBufferAndState(args); + } + } + private void CompleteSend(SocketAsyncEventArgs args) { PacketWriteToken writeToken = (PacketWriteToken) args.UserToken; @@ -366,12 +367,12 @@ namespace NetSharp.Raw.Stream private readonly struct PacketReadToken { - public readonly int BytesToTransfer; - public readonly TaskCompletionSource<int> CompletionSource; - public readonly RawStreamPacketHeader? Header; - public readonly Memory<byte> UserDataBuffer; + internal readonly int BytesToTransfer; + internal readonly TaskCompletionSource<int> CompletionSource; + internal readonly RawStreamPacketHeader? Header; + internal readonly Memory<byte> UserDataBuffer; - public PacketReadToken(int bytesToTransfer, in RawStreamPacketHeader? header, in Memory<byte> userDataBuffer, TaskCompletionSource<int> tcs) + internal PacketReadToken(int bytesToTransfer, in RawStreamPacketHeader? header, in Memory<byte> userDataBuffer, TaskCompletionSource<int> tcs) { BytesToTransfer = bytesToTransfer; @@ -385,10 +386,10 @@ namespace NetSharp.Raw.Stream private readonly struct PacketWriteToken { - public readonly int BytesToTransfer; - public readonly TaskCompletionSource<int> CompletionSource; + internal readonly int BytesToTransfer; + internal readonly TaskCompletionSource<int> CompletionSource; - public PacketWriteToken(int bytesToTransfer, TaskCompletionSource<int> tcs) + internal PacketWriteToken(int bytesToTransfer, TaskCompletionSource<int> tcs) { BytesToTransfer = bytesToTransfer; diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamPacket.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamPacket.cs @@ -1,62 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -using NetSharp.Utils.Conversion; - -namespace NetSharp.Raw.Stream -{ - public readonly struct RawStreamPacket - { - public static (RawStreamPacketHeader packetHeader, ReadOnlyMemory<byte> packetData) Deserialise(in Memory<byte> buffer) - { - Memory<byte> serialisedHeader = buffer.Slice(0, RawStreamPacketHeader.TotalSize); - RawStreamPacketHeader header = RawStreamPacketHeader.Deserialise(in serialisedHeader); - - return (header, buffer.Slice(RawStreamPacketHeader.TotalSize)); - } - - public static void Serialise(in Memory<byte> buffer, in RawStreamPacketHeader packetHeader, in ReadOnlyMemory<byte> packetData) - { - packetHeader.Serialise(buffer.Slice(0, RawStreamPacketHeader.TotalSize)); - - packetData.CopyTo(buffer.Slice(RawStreamPacketHeader.TotalSize, packetData.Length)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int TotalPacketSize(in RawStreamPacketHeader packetHeader) - { - return RawStreamPacketHeader.TotalSize + packetHeader.DataSize; - } - } - - public readonly struct RawStreamPacketHeader - { - public const int TotalSize = sizeof(int); - - public readonly int DataSize; - - internal RawStreamPacketHeader(int dataSize) - { - DataSize = dataSize; - } - - public 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); - } - - public void Serialise(in Memory<byte> buffer) - { - Span<byte> serialisedDataSize = EndianAwareBitConverter.GetBytes(DataSize); - serialisedDataSize.CopyTo(buffer.Slice(0, sizeof(int)).Span); - } - - public override string ToString() - { - return $"[Data Segment Size: {DataSize}]"; - } - } -} -\ No newline at end of file diff --git a/NetSharp/NetSharp/Raw/Stream/VariablePacketRawStreamNetworkWriter.cs b/NetSharp/NetSharp/Raw/Stream/VariablePacketRawStreamNetworkWriter.cs @@ -1,359 +0,0 @@ -namespace NetSharp.Raw.Stream -{ - /* - public sealed class VariablePacketRawStreamNetworkWriter : RawStreamNetworkWriter - { - //TODO replace as soon as possible - private const int MESSAGE_SIZE = 8192; - - /// <inheritdoc /> - public VariablePacketRawStreamNetworkWriter(ref Socket rawConnection, EndPoint defaultEndPoint, int maxMessageSize, int pooledBuffersPerBucket = 50, - uint preallocatedStateObjects = 0) : base(ref rawConnection, defaultEndPoint, maxMessageSize, pooledBuffersPerBucket, preallocatedStateObjects) - { - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConfigureReceiveData(SocketAsyncEventArgs args, in RawStreamPacket.Header header) - { - byte[] receiveBuffer = BufferPool.Rent(header.DataSize); - args.SetBuffer(receiveBuffer, 0, header.DataSize); - - AsyncStreamReadToken token = new AsyncStreamReadToken(header.DataSize, 0); - args.UserToken = token; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConfigureReceiveHeader(SocketAsyncEventArgs args) - { - byte[] receiveBuffer = BufferPool.Rent(RawStreamPacket.Header.TotalHeaderSize); - args.SetBuffer(receiveBuffer, 0, RawStreamPacket.Header.TotalHeaderSize); - - AsyncStreamReadToken token = new AsyncStreamReadToken(RawStreamPacket.Header.TotalHeaderSize, 0); - args.UserToken = token; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConfigureSendData(SocketAsyncEventArgs args, in RawStreamPacket.Header header) - { - byte[] receiveBuffer = BufferPool.Rent(header.DataSize); - args.SetBuffer(receiveBuffer, 0, header.DataSize); - - AsyncStreamWriteToken token = new AsyncStreamWriteToken(header.DataSize, 0); - args.UserToken = token; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConfigureSendHeader(SocketAsyncEventArgs args) - { - byte[] receiveBuffer = BufferPool.Rent(RawStreamPacket.Header.TotalHeaderSize); - args.SetBuffer(receiveBuffer, 0, RawStreamPacket.Header.TotalHeaderSize); - - AsyncStreamWriteToken token = new AsyncStreamWriteToken(RawStreamPacket.Header.TotalHeaderSize, 0); - args.UserToken = token; - } - - /// <inheritdoc /> - protected override void CompleteReceive(SocketAsyncEventArgs args) - { - AsyncStreamReadToken token = (AsyncStreamReadToken) args.UserToken; - - byte[] receiveBuffer = args.Buffer; - Memory<byte> receiveBufferMemory = new Memory<byte>(receiveBuffer); - - int expectedBytes = receiveBuffer.Length; - - bool readHeader = expectedBytes == RawStreamPacket.Header.TotalHeaderSize; - - switch (args.SocketError) - { - case SocketError.Success: - int receivedBytes = args.BytesTransferred, totalReceivedBytes = token.TotalReadBytes; - - if (totalReceivedBytes + receivedBytes == expectedBytes) // transmission complete - { - if (readHeader) - { - Memory<byte> headerBuffer = receiveBufferMemory.Slice(0, RawStreamPacket.Header.TotalHeaderSize); - RawStreamPacket.Header header = RawStreamPacket.Header.Deserialise(in headerBuffer); - - //ConfigureReceiveData(args, in header); - - //StartReceive(args); - } - else - { - receiveBuffer.CopyTo(token.UserBuffer); - token.CompletionSource.SetResult(totalReceivedBytes + receivedBytes); - } - } - else if (0 < totalReceivedBytes + receivedBytes && totalReceivedBytes + receivedBytes < expectedBytes) // transmission not complete - { - // update user token to take account of newly read bytes - token = new AsyncStreamReadToken(in token, receivedBytes); - args.UserToken = token; - - args.SetBuffer(totalReceivedBytes, expectedBytes - receivedBytes); - - ContinueReceive(args); - return; - } - else if (receivedBytes == 0) // connection is dead - { - token.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); - } - break; - - case SocketError.OperationAborted: - token.CompletionSource.SetCanceled(); - break; - - default: - int errorCode = (int) args.SocketError; - token.CompletionSource.SetException(new SocketException(errorCode)); - break; - } - - BufferPool.Return(receiveBuffer, true); - ArgsPool.Return(args); - } - - /// <inheritdoc /> - protected override void CompleteSend(SocketAsyncEventArgs args) - { - AsyncStreamWriteToken token = (AsyncStreamWriteToken) args.UserToken; - - byte[] sendBuffer = args.Buffer; - int expectedBytes = sendBuffer.Length; - - switch (args.SocketError) - { - case SocketError.Success: - int sentBytes = args.BytesTransferred, totalSentBytes = token.TotalWrittenBytes; - - if (totalSentBytes + sentBytes == expectedBytes) // transmission complete - { - token.CompletionSource.SetResult(totalSentBytes + sentBytes); - } - else if (0 < totalSentBytes + sentBytes && totalSentBytes + sentBytes < expectedBytes) // transmission not complete - { - // update user token to take account of newly written bytes - token = new AsyncStreamWriteToken(in token, sentBytes); - args.UserToken = token; - - args.SetBuffer(totalSentBytes, expectedBytes - sentBytes); - - ContinueSend(args); - return; - } - else if (sentBytes == 0) // connection is dead - { - token.CompletionSource.SetException(new SocketException((int) SocketError.HostDown)); - } - break; - - case SocketError.OperationAborted: - token.CompletionSource.SetCanceled(); - break; - - default: - int errorCode = (int) args.SocketError; - token.CompletionSource.SetException(new SocketException(errorCode)); - break; - } - - BufferPool.Return(sendBuffer, true); - ArgsPool.Return(args); - } - - /// <inheritdoc /> - public override int Read(ref EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) - { - byte[] transmissionHeaderBuffer = BufferPool.Rent(RawStreamPacket.Header.TotalHeaderSize); - int readHeaderBytes = 0; - - do - { - readHeaderBytes += Connection.Receive(transmissionHeaderBuffer, readHeaderBytes, - RawStreamPacket.Header.TotalHeaderSize - readHeaderBytes, flags); - } while (readHeaderBytes < RawStreamPacket.Header.TotalHeaderSize && readHeaderBytes != 0); - - RawStreamPacket.Header header = RawStreamPacket.Header.Deserialise(transmissionHeaderBuffer); - int totalBytes = header.DataSize; - BufferPool.Return(transmissionHeaderBuffer, true); - - if (totalBytes > readBuffer.Length) - { - throw new ArgumentException("Read buffer is too small to fully contain message.", nameof(readBuffer)); - } - - int readBytes = 0; - byte[] transmissionBuffer = BufferPool.Rent(totalBytes); - - do - { - readBytes += Connection.Receive(transmissionBuffer, readBytes, totalBytes - readBytes, flags); - } while (readBytes < totalBytes && readBytes != 0); - - transmissionBuffer.CopyTo(readBuffer); - BufferPool.Return(transmissionBuffer, true); - - return readBytes; - } - - /// <inheritdoc /> - public override ValueTask<int> ReadAsync(EndPoint remoteEndPoint, Memory<byte> readBuffer, SocketFlags flags = SocketFlags.None) - { - int totalBytes = readBuffer.Length; - if (totalBytes > MESSAGE_SIZE) - { - throw new ArgumentException( - $"Cannot receive a message of size: {totalBytes} bytes; maximum message size: {MESSAGE_SIZE} bytes", - nameof(readBuffer.Length) - ); - } - - TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); - SocketAsyncEventArgs args = ArgsPool.Rent(); - - byte[] transmissionBuffer = BufferPool.Rent(totalBytes); - - args.SetBuffer(transmissionBuffer, 0, MESSAGE_SIZE); - - args.RemoteEndPoint = remoteEndPoint; - args.SocketFlags = flags; - - AsyncStreamReadToken token = new AsyncStreamReadToken(tcs, MESSAGE_SIZE, 0, in readBuffer); - args.UserToken = token; - - if (Connection.ReceiveAsync(args)) - { - return new ValueTask<int>(tcs.Task); - } - - CompleteReceive(args); - - return new ValueTask<int>(tcs.Task); - } - - /// <inheritdoc /> - public override int Write(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None) - { - byte[] transmissionHeaderBuffer = BufferPool.Rent(RawStreamPacket.Header.TotalHeaderSize); - new RawStreamPacket.Header(writeBuffer.Length).Serialise(transmissionHeaderBuffer); - - int writtenHeaderBytes = 0; - do - { - writtenHeaderBytes += Connection.Send(transmissionHeaderBuffer, writtenHeaderBytes, - RawStreamPacket.Header.TotalHeaderSize - writtenHeaderBytes, flags); - } while (writtenHeaderBytes < RawStreamPacket.Header.TotalHeaderSize && writtenHeaderBytes != 0); - - int totalBytes = writeBuffer.Length; - int writtenBytes = 0; - - byte[] transmissionBuffer = BufferPool.Rent(totalBytes); - writeBuffer.CopyTo(transmissionBuffer); - - do - { - writtenBytes += Connection.Send(transmissionBuffer, writtenBytes, totalBytes - writtenBytes, flags); - } while (writtenBytes < totalBytes && writtenBytes != 0); - - BufferPool.Return(transmissionBuffer); - - return writtenBytes; - } - - /// <inheritdoc /> - public override ValueTask<int> WriteAsync(EndPoint remoteEndPoint, ReadOnlyMemory<byte> writeBuffer, SocketFlags flags = SocketFlags.None) - { - int totalBytes = writeBuffer.Length; - if (totalBytes > MESSAGE_SIZE) - { - throw new ArgumentException( - $"Cannot send a message of size: {totalBytes} bytes; maximum message size: {MESSAGE_SIZE} bytes", - nameof(writeBuffer.Length) - ); - } - - TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); - SocketAsyncEventArgs args = ArgsPool.Rent(); - - byte[] transmissionBuffer = BufferPool.Rent(totalBytes); - writeBuffer.CopyTo(transmissionBuffer); - - args.SetBuffer(transmissionBuffer, 0, MESSAGE_SIZE); - - args.RemoteEndPoint = remoteEndPoint; - args.SocketFlags = flags; - - AsyncStreamWriteToken token = new AsyncStreamWriteToken(tcs, MESSAGE_SIZE, 0); - args.UserToken = token; - - if (Connection.SendAsync(args)) - { - return new ValueTask<int>(tcs.Task); - } - - CompleteSend(args); - - return new ValueTask<int>(tcs.Task); - } - - private readonly struct AsyncStreamReadToken - { - public readonly TaskCompletionSource<int> CompletionSource; - public readonly int ExpectedBytes; - public readonly int TotalReadBytes; - public readonly Memory<byte> UserBuffer; - - public AsyncStreamReadToken(TaskCompletionSource<int> completionSource, int expectedBytes, int totalReadBytes, in Memory<byte> userBuffer) - { - CompletionSource = completionSource; - - ExpectedBytes = expectedBytes; - - TotalReadBytes = totalReadBytes; - - UserBuffer = userBuffer; - } - - public AsyncStreamReadToken(in AsyncStreamReadToken previousToken, int newlyReadBytes) - { - CompletionSource = previousToken.CompletionSource; - - ExpectedBytes = previousToken.ExpectedBytes; - - TotalReadBytes = previousToken.TotalReadBytes + newlyReadBytes; - - UserBuffer = previousToken.UserBuffer; - } - } - - private readonly struct AsyncStreamWriteToken - { - public readonly TaskCompletionSource<int> CompletionSource; - public readonly int ExpectedBytes; - public readonly int TotalWrittenBytes; - - public AsyncStreamWriteToken(TaskCompletionSource<int> completionSource, int expectedBytes, int totalWrittenBytes) - { - CompletionSource = completionSource; - - ExpectedBytes = expectedBytes; - - TotalWrittenBytes = totalWrittenBytes; - } - - public AsyncStreamWriteToken(in AsyncStreamWriteToken previousToken, int newlyWrittenBytes) - { - CompletionSource = previousToken.CompletionSource; - - ExpectedBytes = previousToken.ExpectedBytes; - - TotalWrittenBytes = previousToken.TotalWrittenBytes + newlyWrittenBytes; - } - } - } - */ -} -\ No newline at end of file diff --git a/NetSharp/NetSharp/Utils/BiDictionary.cs b/NetSharp/NetSharp/Utils/BiDictionary.cs @@ -1,275 +0,0 @@ -using System.Collections.Concurrent; - -namespace NetSharp.Utils -{ - /// <summary> - /// Represents a concurrent two-way dictionary, that can be indexed by either a key or a value. - /// </summary> - /// <typeparam name="K"> - /// The type of key that will be stored. - /// </typeparam> - /// <typeparam name="V"> - /// The type of value that will be stored. - /// </typeparam> - public class BiDictionary<K, V> - { - /// <summary> - /// Maps keys to their corresponding values. - /// </summary> - private readonly ConcurrentDictionary<K, V> keyToValueMap; - - /// <summary> - /// Maps values to their corresponding keys. - /// </summary> - private readonly ConcurrentDictionary<V, K> valueToKeyMap; - - /// <summary> - /// Initialises a new instance of the <see cref="BiDictionary{K,V}" /> class. - /// </summary> - public BiDictionary() - { - keyToValueMap = new ConcurrentDictionary<K, V>(); - - valueToKeyMap = new ConcurrentDictionary<V, K>(); - } - - /// <summary> - /// Indexes this instance with the given value. - /// </summary> - /// <param name="index"> - /// The value whose key to get or set. - /// </param> - /// <returns> - /// The fetched key. - /// </returns> - public K this[V index] - { - get - { - valueToKeyMap.TryGetValue(index, out K key); - - return key; - } - - set => valueToKeyMap.AddOrUpdate(index, value, (v, k) => value); - } - - /// <summary> - /// Indexes this instance with the given key. - /// </summary> - /// <param name="index"> - /// The key whose value to get or set. - /// </param> - /// <returns> - /// The fetched value. - /// </returns> - public V this[K index] - { - get - { - keyToValueMap.TryGetValue(index, out V value); - - return value; - } - - set => keyToValueMap.AddOrUpdate(index, value, (k, v) => value); - } - - /// <summary> - /// Clears this instance's <see cref="keyToValueMap" /> and <see cref="valueToKeyMap" />. - /// </summary> - public void Clear() - { - keyToValueMap.Clear(); - valueToKeyMap.Clear(); - } - - /// <summary> - /// Whether this instance contains the given key. - /// </summary> - /// <param name="key"> - /// The key to check. - /// </param> - /// <returns> - /// Whether the given key was found. - /// </returns> - public bool ContainsKey(in K key) - { - return keyToValueMap.ContainsKey(key); - } - - /// <summary> - /// Whether this instance contains the given value. - /// </summary> - /// <param name="value"> - /// The value to check. - /// </param> - /// <returns> - /// Whether the given value was found. - /// </returns> - public bool ContainsValue(in V value) - { - return valueToKeyMap.ContainsKey(value); - } - - /// <summary> - /// Attempts to set the key associated with the given value. - /// </summary> - /// <param name="value"> - /// The value whose key to set. - /// </param> - /// <param name="key"> - /// The new value for the value's associated key. - /// </param> - /// <returns> - /// Whether the new key was correctly set. - /// </returns> - public void SetOrUpdateKey(V value, K key) - { - valueToKeyMap.AddOrUpdate(value, key, (v, k) => key); - - keyToValueMap.AddOrUpdate(key, value, (k, v) => value); - } - - /// <summary> - /// Attempts to set the value associated with the given key. - /// </summary> - /// <param name="key"> - /// The key whose value to set. - /// </param> - /// <param name="value"> - /// The new value for the key's associated value. - /// </param> - /// <returns> - /// Whether the new value was correctly set. - /// </returns> - public void SetOrUpdateValue(K key, V value) - { - keyToValueMap.AddOrUpdate(key, value, (k, v) => value); - - valueToKeyMap.AddOrUpdate(value, key, (v, k) => key); - } - - /// <summary> - /// Attempts to remove the key associated with the given value. - /// </summary> - /// <param name="value"> - /// The value whose key to remove. - /// </param> - /// <param name="key"> - /// The old key value. - /// </param> - /// <returns> - /// Whether the given value had a valid key associated with it. - /// </returns> - public bool TryClearKey(in V value, out K key) - { - bool clearedValue = valueToKeyMap.TryRemove(value, out key); - - bool clearedKey = keyToValueMap.TryRemove(key, out _); - - return clearedValue && clearedKey; - } - - /// <summary> - /// Attempts to remove the value associated with the given key. - /// </summary> - /// <param name="key"> - /// The key whose value to remove. - /// </param> - /// <param name="value"> - /// The old value. - /// </param> - /// <returns> - /// Whether the given key had a valid valid associated with it. - /// </returns> - public bool TryClearValue(in K key, out V value) - { - bool clearedKey = keyToValueMap.TryRemove(key, out value); - - bool clearedValue = valueToKeyMap.TryRemove(value, out _); - - return clearedKey && clearedValue; - } - - /// <summary> - /// Attempts to get the key associated with the given value. - /// </summary> - /// <param name="value"> - /// The value whose key to get. - /// </param> - /// <param name="key"> - /// The returned key. - /// </param> - /// <returns> - /// Whether the given value has a valid key associated with it. - /// </returns> - public bool TryGetKey(in V value, out K key) - { - return valueToKeyMap.TryGetValue(value, out key); - } - - /// <summary> - /// Attempts to get the value associated with the given key. - /// </summary> - /// <param name="key"> - /// The key whose value to get. - /// </param> - /// <param name="value"> - /// The returned value. - /// </param> - /// <returns> - /// Whether the given key as a valid value associated with it. - /// </returns> - public bool TryGetValue(in K key, out V value) - { - return keyToValueMap.TryGetValue(key, out value); - } - - /// <summary> - /// Attempts to set the key associated with the given value. - /// </summary> - /// <param name="value"> - /// The value whose key to set. - /// </param> - /// <param name="key"> - /// The key which should be set for the given value. - /// </param> - /// <returns> - /// Whether the given value was successfully set. - /// </returns> - public bool TrySetKey(in V value, in K key) - { - K newKey = key; - V newValue = value; - - K setKey = valueToKeyMap.AddOrUpdate(value, v => newKey, (v, k) => newKey); - V setValue = keyToValueMap.AddOrUpdate(key, k => newValue, (k, v) => newValue); - - return (setKey?.Equals(key) ?? false) && (setValue?.Equals(value) ?? false); - } - - /// <summary> - /// Attempts to set the value associated with the given key. - /// </summary> - /// <param name="key"> - /// The key whose value to set. - /// </param> - /// <param name="value"> - /// The value which should be set for the given key. - /// </param> - /// <returns> - /// Whether the given key was successfully set. - /// </returns> - public bool TrySetValue(in K key, in V value) - { - V newValue = value; - K newKey = key; - - V setValue = keyToValueMap.AddOrUpdate(key, k => newValue, (k, v) => newValue); - K setKey = valueToKeyMap.AddOrUpdate(value, v => newKey, (v, k) => newKey); - - return (setValue?.Equals(value) ?? false) && (setKey?.Equals(key) ?? false); - } - } -} -\ No newline at end of file diff --git a/NetSharp/NetSharp/Utils/Conversion/EndianAwareBitConverter.cs b/NetSharp/NetSharp/Utils/Conversion/EndianAwareBitConverter.cs @@ -6,7 +6,7 @@ namespace NetSharp.Utils.Conversion /// <summary> /// Wraps the <see cref="BitConverter" /> class to provide conversion that is endian-aware. /// </summary> - public static class EndianAwareBitConverter + internal static class EndianAwareBitConverter { /// <summary> /// Reverses the given bytes if the endian-nes doesn't match. @@ -24,140 +24,140 @@ namespace NetSharp.Utils.Conversion /// <inheritdoc cref="BitConverter.GetBytes(bool)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(bool value, bool littleEndian = false) + internal static Span<byte> GetBytes(bool value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(char)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(char value, bool littleEndian = false) + internal static Span<byte> GetBytes(char value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(double)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(double value, bool littleEndian = false) + internal static Span<byte> GetBytes(double value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(float)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(float value, bool littleEndian = false) + internal static Span<byte> GetBytes(float value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(int)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(int value, bool littleEndian = false) + internal static Span<byte> GetBytes(int value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(long)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(long value, bool littleEndian = false) + internal static Span<byte> GetBytes(long value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(short)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(short value, bool littleEndian = false) + internal static Span<byte> GetBytes(short value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(uint)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(uint value, bool littleEndian = false) + internal static Span<byte> GetBytes(uint value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(ulong)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(ulong value, bool littleEndian = false) + internal static Span<byte> GetBytes(ulong value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.GetBytes(ushort)" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<byte> GetBytes(ushort value, bool littleEndian = false) + internal static Span<byte> GetBytes(ushort value, bool littleEndian = false) { return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); } /// <inheritdoc cref="BitConverter.ToBoolean(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool ToBoolean(Span<byte> bytes, bool littleEndian = false) + internal static bool ToBoolean(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToBoolean(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToChar(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static char ToChar(Span<byte> bytes, bool littleEndian = false) + internal static char ToChar(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToChar(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToDouble(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double ToDouble(Span<byte> bytes, bool littleEndian = false) + internal static double ToDouble(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToDouble(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToInt16(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short ToInt16(Span<byte> bytes, bool littleEndian = false) + internal static short ToInt16(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToInt16(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToInt32(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ToInt32(Span<byte> bytes, bool littleEndian = false) + internal static int ToInt32(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToInt32(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToInt64(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long ToInt64(Span<byte> bytes, bool littleEndian = false) + internal static long ToInt64(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToInt64(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToSingle(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float ToSingle(Span<byte> bytes, bool littleEndian = false) + internal static float ToSingle(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToSingle(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToUInt16(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort ToUInt16(byte[] bytes, bool littleEndian = false) + internal static ushort ToUInt16(byte[] bytes, bool littleEndian = false) { return BitConverter.ToUInt16(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToUInt32(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint ToUInt32(Span<byte> bytes, bool littleEndian = false) + internal static uint ToUInt32(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToUInt32(ReverseAsNeeded(bytes, littleEndian)); } /// <inheritdoc cref="BitConverter.ToUInt64(ReadOnlySpan{byte})" /> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ulong ToUInt64(Span<byte> bytes, bool littleEndian = false) + internal static ulong ToUInt64(Span<byte> bytes, bool littleEndian = false) { return BitConverter.ToUInt64(ReverseAsNeeded(bytes, littleEndian)); } diff --git a/NetSharp/NetSharp/Utils/SlimObjectPool.cs b/NetSharp/NetSharp/Utils/SlimObjectPool.cs @@ -9,7 +9,7 @@ namespace NetSharp.Utils /// <typeparam name="T"> /// The type of item stored in the pool. /// </typeparam> - public sealed class SlimObjectPool<T> : IDisposable where T : class + internal sealed class SlimObjectPool<T> : IDisposable { private readonly CanRebufferObjectPredicate canObjectBeRebufferedPredicate; @@ -39,7 +39,7 @@ namespace NetSharp.Utils /// <param name="baseCollection"> /// The underlying pooled object buffer to use. /// </param> - public SlimObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, + internal SlimObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, in DestroyObjectDelegate destroyDelegate, in CanRebufferObjectPredicate rebufferPredicate, in IProducerConsumerCollection<T> baseCollection) { @@ -69,7 +69,7 @@ namespace NetSharp.Utils /// <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, + internal SlimObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, in DestroyObjectDelegate destroyDelegate, in CanRebufferObjectPredicate rebufferPredicate) : this(in createDelegate, in resetDelegate, in destroyDelegate, in rebufferPredicate, new ConcurrentBag<T>()) { @@ -85,7 +85,7 @@ namespace NetSharp.Utils /// <returns> /// Whether the given instance should be placed back into the pool. /// </returns> - public delegate bool CanRebufferObjectPredicate(ref T instance); + internal delegate bool CanRebufferObjectPredicate(ref T instance); /// <summary> /// Delegate method for creating fresh <typeparamref name="T" /> instances to be stored in the pool. @@ -93,7 +93,7 @@ namespace NetSharp.Utils /// <returns> /// A configured <typeparamref name="T" /> instance. /// </returns> - public delegate T CreateObjectDelegate(); + internal delegate T CreateObjectDelegate(); /// <summary> /// Delegate method to destroy a used <paramref name="instance" /> which cannot be reused. @@ -101,7 +101,7 @@ namespace NetSharp.Utils /// <param name="instance"> /// The instance to destroy. /// </param> - public delegate void DestroyObjectDelegate(T instance); + internal delegate void DestroyObjectDelegate(T instance); /// <summary> /// Delegate method to reset a used <paramref name="instance" /> before placing it back into the pool. @@ -109,16 +109,7 @@ namespace NetSharp.Utils /// <param name="instance"> /// The instance which should be reset. /// </param> - public delegate void ResetObjectDelegate(ref T instance); - - /// <inheritdoc /> - public void Dispose() - { - foreach (T pooledObject in objectBuffer) - { - destroyObjectDelegate(pooledObject); - } - } + internal delegate void ResetObjectDelegate(ref T instance); /// <summary> /// Leases a new <typeparamref name="T" /> instance from the pool, and returns it. @@ -126,7 +117,7 @@ namespace NetSharp.Utils /// <returns> /// The <typeparamref name="T" /> instance which was fetched from the pool. /// </returns> - public T Rent() + internal T Rent() { return objectBuffer.TryTake(out T result) ? result : createObjectDelegate(); } @@ -137,7 +128,7 @@ namespace NetSharp.Utils /// <param name="instance"> /// The previously leased instance which should be returned. /// </param> - public void Return(T instance) + internal void Return(T instance) { if (canObjectBeRebufferedPredicate(ref instance)) { @@ -150,5 +141,14 @@ namespace NetSharp.Utils destroyObjectDelegate(instance); } } + + /// <inheritdoc /> + public void Dispose() + { + foreach (T pooledObject in objectBuffer) + { + destroyObjectDelegate(pooledObject); + } + } } } \ No newline at end of file diff --git a/NetSharp/NetSharp/Utils/TransmissionResult.cs b/NetSharp/NetSharp/Utils/TransmissionResult.cs @@ -1,77 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; - -namespace NetSharp.Utils -{ - /// <summary> - /// Represents the result of a socket transmission. - /// </summary> - public readonly struct TransmissionResult - { - /// <summary> - /// Represents an asynchronous transmission which timed out. - /// </summary> - internal static readonly TransmissionResult Timeout = new TransmissionResult(); - - /// <summary> - /// The byte buffer that was transmitted across the network. - /// </summary> - public readonly Memory<byte> Buffer; - - /// <summary> - /// The number of bytes that were transmitted across the network. - /// </summary> - public readonly int Count; - - /// <summary> - /// The remote endpoint to which the buffer was transmitted. - /// </summary> - public readonly EndPoint RemoteEndPoint; - - /// <summary> - /// Initialises a new instance of the <see cref="TransmissionResult" /> struct. - /// </summary> - /// <param name="args"> - /// The socket arguments associated with the transmission. - /// </param> - internal TransmissionResult(in SocketAsyncEventArgs args) - { - Buffer = args.MemoryBuffer; - Count = args.BytesTransferred; - RemoteEndPoint = args.RemoteEndPoint; - } - - /// <summary> - /// Initialises a new instance of the <see cref="TransmissionResult" /> struct. - /// </summary> - /// <param name="buffer"> - /// The buffer associated with the transmission. - /// </param> - /// <param name="count"> - /// The number of bytes written to or read from the buffer. - /// </param> - /// <param name="remoteEndPoint"> - /// The remote end point associated with the transmission. - /// </param> - internal TransmissionResult(in byte[] buffer, in int count, in EndPoint remoteEndPoint) - { - Buffer = buffer; - Count = count; - RemoteEndPoint = remoteEndPoint; - } - - /// <summary> - /// Checks whether this instance represents a timed out transmission. - /// </summary> - /// <returns> - /// Whether this instance has timed out. - /// </returns> - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TimedOut() - { - return Equals(Timeout); - } - } -} -\ No newline at end of file diff --git a/NetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkReaderBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkReaderBenchmark.cs @@ -13,15 +13,12 @@ namespace NetSharpExamples.Benchmarks.Datagram_Network_Connection_Benchmarks internal class DatagramNetworkReaderBenchmark : INetSharpBenchmark { private const int PacketSize = 8192, PacketCount = 1_000_000, ClientCount = 12; - + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); private double[] ClientBandwidths; - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - - public static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); - /// <inheritdoc /> public string Name { get; } = "Raw Datagram Network Reader Benchmark"; diff --git a/NetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkWriterAsyncBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkWriterAsyncBenchmark.cs @@ -12,12 +12,10 @@ namespace NetSharpExamples.Benchmarks.Datagram_Network_Connection_Benchmarks internal class DatagramNetworkWriterAsyncBenchmark : INetSharpBenchmark { private const int PacketSize = 8192, PacketCount = 1_000_000; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - - public static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); /// <inheritdoc /> public string Name { get; } = "Raw Datagram Network Writer Benchmark (Asynchronous)"; diff --git a/NetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkWriterSyncBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/Datagram Network Connection Benchmarks/DatagramNetworkWriterSyncBenchmark.cs @@ -12,12 +12,10 @@ namespace NetSharpExamples.Benchmarks.Datagram_Network_Connection_Benchmarks internal class DatagramNetworkWriterSyncBenchmark : INetSharpBenchmark { private const int PacketSize = 8192, PacketCount = 1_000_000; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - - public static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); /// <inheritdoc /> public string Name { get; } = "Raw Datagram Network Writer Benchmark (Synchronous)"; diff --git a/NetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkReaderBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkReaderBenchmark.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using NetSharp.Packets; using NetSharp.Raw.Stream; namespace NetSharpExamples.Benchmarks.Stream_Network_Connection_Benchmarks @@ -13,15 +14,12 @@ namespace NetSharpExamples.Benchmarks.Stream_Network_Connection_Benchmarks internal class StreamNetworkReaderBenchmark : INetSharpBenchmark { private const int PacketSize = 8192, PacketCount = 1_000_000, ClientCount = 12; - + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); private double[] ClientBandwidths; - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - - public static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); - /// <inheritdoc /> public string Name { get; } = "Raw Stream Network Reader Benchmark"; diff --git a/NetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkWriterAsyncBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkWriterAsyncBenchmark.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using NetSharp.Packets; using NetSharp.Raw.Stream; namespace NetSharpExamples.Benchmarks.Stream_Network_Connection_Benchmarks @@ -12,12 +13,10 @@ namespace NetSharpExamples.Benchmarks.Stream_Network_Connection_Benchmarks internal class StreamNetworkWriterAsyncBenchmark : INetSharpBenchmark { private const int PacketSize = 8192, PacketCount = 1_000_000; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - - public static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); /// <inheritdoc /> public string Name { get; } = "Raw Stream Network Writer Benchmark (Asynchronous)"; diff --git a/NetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkWriterSyncBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/Stream Network Connection Benchmarks/StreamNetworkWriterSyncBenchmark.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using NetSharp.Packets; using NetSharp.Raw.Stream; namespace NetSharpExamples.Benchmarks.Stream_Network_Connection_Benchmarks @@ -12,12 +13,10 @@ namespace NetSharpExamples.Benchmarks.Stream_Network_Connection_Benchmarks internal class StreamNetworkWriterSyncBenchmark : INetSharpBenchmark { private const int PacketSize = 8192, PacketCount = 1_000_000; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - - public static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly ManualResetEventSlim ServerReadyEvent = new ManualResetEventSlim(); /// <inheritdoc /> public string Name { get; } = "Raw Stream Network Writer Benchmark (Synchronous)"; diff --git a/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkReaderExample.cs b/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkReaderExample.cs @@ -11,9 +11,8 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples internal class DatagramNetworkReaderExample : INetSharpExample { private const int PacketSize = 8192, ExpectedClientCount = 8; - - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; /// <inheritdoc /> public string Name { get; } = "Datagram Network Reader Example"; diff --git a/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterAsyncExample.cs b/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterAsyncExample.cs @@ -11,10 +11,9 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples internal class DatagramNetworkWriterAsyncExample : INetSharpExample { private const int PacketSize = 8192; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; /// <inheritdoc /> public string Name { get; } = "Datagram Network Writer Example (Asynchronous)"; @@ -33,25 +32,32 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples EndPoint remoteEndPoint = ServerEndPoint; - while (true) + try { - int sent = await writer.WriteAsync(remoteEndPoint, transmissionBuffer); - - lock (typeof(Console)) + while (true) { - Console.WriteLine($"Sent {sent} bytes to {remoteEndPoint}!"); - } + //TODO add user input - int received = await writer.ReadAsync(remoteEndPoint, transmissionBuffer); + int sent = await writer.WriteAsync(remoteEndPoint, transmissionBuffer); - lock (typeof(Console)) - { - Console.WriteLine($"Received {received} bytes from {remoteEndPoint}!"); + lock (typeof(Console)) + { + Console.WriteLine($"Sent {sent} bytes to {remoteEndPoint}!"); + } + + int received = await writer.ReadAsync(remoteEndPoint, transmissionBuffer); + + lock (typeof(Console)) + { + Console.WriteLine($"Received {received} bytes from {remoteEndPoint}!"); + } } } - - rawSocket.Close(); - rawSocket.Dispose(); + finally + { + rawSocket.Close(); + rawSocket.Dispose(); + } } } } \ No newline at end of file diff --git a/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterSyncExample.cs b/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterSyncExample.cs @@ -11,10 +11,9 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples internal class DatagramNetworkWriterSyncExample : INetSharpExample { private const int PacketSize = 8192; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; /// <inheritdoc /> public string Name { get; } = "Datagram Network Writer Example (Synchronous)"; @@ -33,25 +32,32 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples EndPoint remoteEndPoint = ServerEndPoint; - while (true) + try { - int sent = writer.Write(remoteEndPoint, transmissionBuffer); - - lock (typeof(Console)) + while (true) { - Console.WriteLine($"Sent {sent} bytes to {remoteEndPoint}!"); - } + // TODO add user input - int received = writer.Read(ref remoteEndPoint, transmissionBuffer); + int sent = writer.Write(remoteEndPoint, transmissionBuffer); - lock (typeof(Console)) - { - Console.WriteLine($"Received {received} bytes from {remoteEndPoint}!"); + lock (typeof(Console)) + { + Console.WriteLine($"Sent {sent} bytes to {remoteEndPoint}!"); + } + + int received = writer.Read(ref remoteEndPoint, transmissionBuffer); + + lock (typeof(Console)) + { + Console.WriteLine($"Received {received} bytes from {remoteEndPoint}!"); + } } } - - rawSocket.Close(); - rawSocket.Dispose(); + finally + { + rawSocket.Close(); + rawSocket.Dispose(); + } return Task.CompletedTask; } diff --git a/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/RawStreamChatServer.cs b/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/RawStreamChatServer.cs @@ -12,15 +12,13 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples internal class RawStreamChatServer : INetSharpExample { private static readonly int ChatPacketSize = 8192; + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; private static readonly EndPoint DefaultEndPoint = new IPEndPoint(IPAddress.Any, 0); private static readonly ushort InitialClientCount = 4; - + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; private static readonly ManualResetEventSlim serverStartedEvent = new ManualResetEventSlim(false); - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; - public string Name => "Raw Stream Chat Server"; private static async Task ClientTask() diff --git a/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkReaderExample.cs b/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkReaderExample.cs @@ -11,9 +11,8 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples internal class StreamNetworkReaderExample : INetSharpExample { private const int PacketSize = 8192, ExpectedClientCount = 8; - - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; /// <inheritdoc /> public string Name { get; } = "Raw Stream Network Reader Example"; diff --git a/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterAsyncExample.cs b/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterAsyncExample.cs @@ -11,10 +11,9 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples internal class StreamNetworkWriterAsyncExample : INetSharpExample { private const int PacketSize = 8192; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; /// <inheritdoc /> public string Name { get; } = "Raw Stream Network Writer Example (Asynchronous)"; @@ -38,6 +37,8 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples { while (true) { + // TODO add user input + int sent = await writer.WriteAsync(remoteEndPoint, transmissionBuffer); lock (typeof(Console)) diff --git a/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterSyncExample.cs b/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterSyncExample.cs @@ -11,10 +11,9 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples internal class StreamNetworkWriterSyncExample : INetSharpExample { private const int PacketSize = 8192; - - public static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; - public static readonly Encoding ServerEncoding = Program.DefaultEncoding; - public static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; + private static readonly EndPoint ClientEndPoint = Program.DefaultClientEndPoint; + private static readonly Encoding ServerEncoding = Program.DefaultEncoding; + private static readonly EndPoint ServerEndPoint = Program.DefaultServerEndPoint; /// <inheritdoc /> public string Name { get; } = "Raw Stream Network Writer Example (Synchronous)"; @@ -38,6 +37,8 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples { while (true) { + // TODO add user input + int sent = writer.Write(remoteEndPoint, transmissionBuffer); lock (typeof(Console))