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:
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;
}