NetSharp

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

commit f9030c42836d1192587ff4ba128a9062ae25f406
parent 8344ed3d9eec5a4023e3032266f4219c0a1ae64a
Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com>
Date:   Tue,  5 May 2020 09:44:45 +0100

StreamReader wont accept new connections properly!

Diffstat:
MNetSharp/NetSharp/Raw/Datagram/DatagramNetworkWriter.cs | 2++
MNetSharp/NetSharp/Raw/Stream/StreamNetworkReader.cs | 45++++++++++++++++++++++++---------------------
MNetSharp/NetSharp/Raw/Stream/StreamNetworkWriter.cs | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
MNetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterAsyncExample.cs | 2++
MNetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterSyncExample.cs | 2++
MNetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterAsyncExample.cs | 2++
MNetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterSyncExample.cs | 2++
MNetSharp/NetSharpExamples/Program.cs | 10++++++----
8 files changed, 103 insertions(+), 36 deletions(-)

diff --git a/NetSharp/NetSharp/Raw/Datagram/DatagramNetworkWriter.cs b/NetSharp/NetSharp/Raw/Datagram/DatagramNetworkWriter.cs @@ -207,6 +207,7 @@ namespace NetSharp.Raw.Datagram if (Connection.ReceiveFromAsync(args)) return new ValueTask<int>(tcs.Task); + // inlining CompleteReceiveFrom(SocketAsyncEventArgs) for performance int result = args.BytesTransferred; transmissionBuffer.CopyTo(readBuffer); @@ -268,6 +269,7 @@ namespace NetSharp.Raw.Datagram if (Connection.SendToAsync(args)) return new ValueTask<int>(tcs.Task); + // inlining CompleteSendTo(SocketAsyncEventArgs) for performance int result = args.BytesTransferred; BufferPool.Return(transmissionBuffer, true); diff --git a/NetSharp/NetSharp/Raw/Stream/StreamNetworkReader.cs b/NetSharp/NetSharp/Raw/Stream/StreamNetworkReader.cs @@ -25,6 +25,8 @@ namespace NetSharp.Raw.Stream clientSocket.Dispose(); StateObjectPool.Return(args); + + StartDefaultAccept(); } private void CompleteAccept(SocketAsyncEventArgs args) @@ -53,25 +55,12 @@ namespace NetSharp.Raw.Stream case SocketError.Success: int receivedBytes = args.BytesTransferred, totalReceivedBytes = token.BytesTransferred; - if (receivedBytes == 0) // connection is dead - { - CloseClientConnection(args); - } - else if (0 < totalReceivedBytes + receivedBytes && totalReceivedBytes + receivedBytes < expectedBytes) // transmission not complete - { - token = new TransmissionToken(in token, args.BytesTransferred); - args.UserToken = token; - - args.SetBuffer(totalReceivedBytes, expectedBytes - receivedBytes); - - ContinueReceive(args); - } - else if (totalReceivedBytes + receivedBytes == expectedBytes) // transmission complete + if (totalReceivedBytes + receivedBytes == expectedBytes) // transmission complete { byte[] responseBufferHandle = BufferPool.Rent(expectedBytes); bool responseExists = - RequestHandler(args.RemoteEndPoint, receiveBuffer, totalReceivedBytes + receivedBytes, responseBufferHandle); + RequestHandler(args.AcceptSocket.RemoteEndPoint, receiveBuffer, totalReceivedBytes + receivedBytes, responseBufferHandle); BufferPool.Return(receiveBuffer, true); if (responseExists) @@ -89,6 +78,19 @@ namespace NetSharp.Raw.Stream StartReceive(args); } + else if (0 < totalReceivedBytes + receivedBytes && totalReceivedBytes + receivedBytes < expectedBytes) // transmission not complete + { + token = new TransmissionToken(in token, args.BytesTransferred); + args.UserToken = token; + + args.SetBuffer(totalReceivedBytes, expectedBytes - receivedBytes); + + ContinueReceive(args); + } + else if (receivedBytes == 0) // connection is dead + { + CloseClientConnection(args); + } break; default: @@ -109,9 +111,11 @@ namespace NetSharp.Raw.Stream case SocketError.Success: int sentBytes = args.BytesTransferred, totalSentBytes = token.BytesTransferred; - if (sentBytes == 0) // connection is dead + if (totalSentBytes + sentBytes == expectedBytes) // transmission complete { - CloseClientConnection(args); + BufferPool.Return(sendBuffer, true); + + StartReceive(args); } else if (0 < totalSentBytes + sentBytes && totalSentBytes + sentBytes < expectedBytes) // transmission not complete { @@ -122,11 +126,9 @@ namespace NetSharp.Raw.Stream ContinueSend(args); } - else if (totalSentBytes + sentBytes == expectedBytes) // transmission complete + else if (sentBytes == 0) // connection is dead { - BufferPool.Return(sendBuffer, true); - - StartReceive(args); + CloseClientConnection(args); } break; @@ -273,6 +275,7 @@ namespace NetSharp.Raw.Stream /// <inheritdoc /> protected override void ResetStateObject(ref SocketAsyncEventArgs instance) { + instance.AcceptSocket = null; } /// <inheritdoc /> diff --git a/NetSharp/NetSharp/Raw/Stream/StreamNetworkWriter.cs b/NetSharp/NetSharp/Raw/Stream/StreamNetworkWriter.cs @@ -64,8 +64,8 @@ namespace NetSharp.Raw.Stream { AsyncStreamReadToken token = (AsyncStreamReadToken)args.UserToken; - byte[] receiveBufferHandle = args.Buffer; - int expectedBytes = receiveBufferHandle.Length; + byte[] receiveBuffer = args.Buffer; + int expectedBytes = receiveBuffer.Length; switch (args.SocketError) { @@ -74,8 +74,8 @@ namespace NetSharp.Raw.Stream if (totalReceivedBytes + receivedBytes == expectedBytes) // transmission complete { - receiveBufferHandle.CopyTo(token.UserBuffer); - token.CompletionSource.SetResult(args.BytesTransferred); + receiveBuffer.CopyTo(token.UserBuffer); + token.CompletionSource.SetResult(totalReceivedBytes + receivedBytes); } else if (0 < totalReceivedBytes + receivedBytes && totalReceivedBytes + receivedBytes < expectedBytes) // transmission not complete { @@ -104,7 +104,7 @@ namespace NetSharp.Raw.Stream break; } - BufferPool.Return(receiveBufferHandle, true); + BufferPool.Return(receiveBuffer, true); StateObjectPool.Return(args); } @@ -112,8 +112,8 @@ namespace NetSharp.Raw.Stream { AsyncStreamWriteToken token = (AsyncStreamWriteToken)args.UserToken; - byte[] sendBufferHandle = args.Buffer; - int expectedBytes = sendBufferHandle.Length; + byte[] sendBuffer = args.Buffer; + int expectedBytes = sendBuffer.Length; switch (args.SocketError) { @@ -122,7 +122,7 @@ namespace NetSharp.Raw.Stream if (totalSentBytes + sentBytes == expectedBytes) // transmission complete { - token.CompletionSource.SetResult(args.BytesTransferred); + token.CompletionSource.SetResult(totalSentBytes + sentBytes); } else if (0 < totalSentBytes + sentBytes && totalSentBytes + sentBytes < expectedBytes) // transmission not complete { @@ -151,7 +151,7 @@ namespace NetSharp.Raw.Stream break; } - BufferPool.Return(sendBufferHandle, true); + BufferPool.Return(sendBuffer, true); StateObjectPool.Return(args); } @@ -318,7 +318,34 @@ namespace NetSharp.Raw.Stream AsyncStreamReadToken token = new AsyncStreamReadToken(tcs, 0, in readBuffer); args.UserToken = token; - if (!Connection.ReceiveAsync(args)) CompleteReceive(args); + if (Connection.ReceiveAsync(args)) return new ValueTask<int>(tcs.Task); + + // inlining CompleteReceive(SocketAsyncEventArgs) for performance + int receivedBytes = args.BytesTransferred, totalReceivedBytes = token.TotalReadBytes; + + if (totalReceivedBytes + receivedBytes == BufferSize) // transmission complete + { + transmissionBuffer.CopyTo(readBuffer); + + BufferPool.Return(transmissionBuffer, true); + StateObjectPool.Return(args); + + return new ValueTask<int>(totalReceivedBytes + receivedBytes); + } + else if (0 < totalReceivedBytes + receivedBytes && totalReceivedBytes + receivedBytes < BufferSize) // 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, BufferSize - receivedBytes); + + ContinueReceive(args); + } + else if (receivedBytes == 0) // connection is dead + { + token.CompletionSource.SetException(new SocketException((int)SocketError.HostDown)); + } return new ValueTask<int>(tcs.Task); } @@ -376,7 +403,32 @@ namespace NetSharp.Raw.Stream AsyncStreamWriteToken token = new AsyncStreamWriteToken(tcs, 0); args.UserToken = token; - if (!Connection.SendAsync(args)) CompleteSend(args); + if (Connection.SendAsync(args)) return new ValueTask<int>(tcs.Task); + + // inlining CompleteSend(SocketAsyncEventArgs) for performance + int sentBytes = args.BytesTransferred, totalSentBytes = token.TotalWrittenBytes; + + if (totalSentBytes + sentBytes == BufferSize) // transmission complete + { + BufferPool.Return(transmissionBuffer, true); + StateObjectPool.Return(args); + + return new ValueTask<int>(totalSentBytes + sentBytes); + } + else if (0 < totalSentBytes + sentBytes && totalSentBytes + sentBytes < BufferSize) // 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, BufferSize - sentBytes); + + ContinueSend(args); + } + else if (sentBytes == 0) // connection is dead + { + token.CompletionSource.SetException(new SocketException((int)SocketError.HostDown)); + } return new ValueTask<int>(tcs.Task); } diff --git a/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterAsyncExample.cs b/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterAsyncExample.cs @@ -3,6 +3,7 @@ using System; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples @@ -13,6 +14,7 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples public static readonly EndPoint ClientEndPoint = new IPEndPoint(IPAddress.Loopback, 0); + public static readonly Encoding ServerEncoding = DatagramNetworkReaderExample.ServerEncoding; public static readonly EndPoint ServerEndPoint = DatagramNetworkReaderExample.ServerEndPoint; /// <inheritdoc /> diff --git a/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterSyncExample.cs b/NetSharp/NetSharpExamples/Examples/Datagram Network Connection Examples/DatagramNetworkWriterSyncExample.cs @@ -3,6 +3,7 @@ using System; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples @@ -13,6 +14,7 @@ namespace NetSharpExamples.Examples.Datagram_Network_Connection_Examples public static readonly EndPoint ClientEndPoint = new IPEndPoint(IPAddress.Loopback, 0); + public static readonly Encoding ServerEncoding = DatagramNetworkReaderExample.ServerEncoding; public static readonly EndPoint ServerEndPoint = DatagramNetworkReaderExample.ServerEndPoint; /// <inheritdoc /> diff --git a/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterAsyncExample.cs b/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterAsyncExample.cs @@ -3,6 +3,7 @@ using System; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples @@ -13,6 +14,7 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples public static readonly EndPoint ClientEndPoint = new IPEndPoint(IPAddress.Loopback, 0); + public static readonly Encoding ServerEncoding = StreamNetworkReaderExample.ServerEncoding; public static readonly EndPoint ServerEndPoint = StreamNetworkReaderExample.ServerEndPoint; /// <inheritdoc /> diff --git a/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterSyncExample.cs b/NetSharp/NetSharpExamples/Examples/Stream Network Connection Examples/StreamNetworkWriterSyncExample.cs @@ -3,6 +3,7 @@ using System; using System.Net; using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples @@ -13,6 +14,7 @@ namespace NetSharpExamples.Examples.Stream_Network_Connection_Examples public static readonly EndPoint ClientEndPoint = new IPEndPoint(IPAddress.Loopback, 0); + public static readonly Encoding ServerEncoding = StreamNetworkReaderExample.ServerEncoding; public static readonly EndPoint ServerEndPoint = StreamNetworkReaderExample.ServerEndPoint; /// <inheritdoc /> diff --git a/NetSharp/NetSharpExamples/Program.cs b/NetSharp/NetSharpExamples/Program.cs @@ -59,7 +59,7 @@ namespace NetSharpExamples Console.WriteLine("Available Examples:"); for (int i = 0; i < Examples.Count; i++) { - Console.WriteLine($"\t{i} - {Examples[i].Name}"); + Console.WriteLine($"\t{i:D2} - {Examples[i].Name}"); } while (true) @@ -77,9 +77,11 @@ namespace NetSharpExamples continue; } - Console.WriteLine($"Starting \'{Examples[choice].Name}\'..."); - Examples[choice].RunAsync().GetAwaiter().GetResult(); - Console.WriteLine($"Finished \'{Examples[choice].Name}\'!"); + INetSharpExample selectedExample = Examples[choice]; + + Console.WriteLine($"Starting \'{selectedExample.Name}\'..."); + selectedExample.RunAsync().GetAwaiter().GetResult(); + Console.WriteLine($"Finished \'{selectedExample.Name}\'!"); break; }