NetSharp

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

commit 9423fd896148db1ad57936a4cd5ecdee1ef62bf6
parent 1529d47f186fb7c229dae3eedaedddb9ed999ffb
Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com>
Date:   Tue, 25 Aug 2020 22:59:04 +0100

Added exception logging on benchmarks.
---
Fixed bug with UDP writer benchmakrs, where the server would not be shutdown and was left open.

Diffstat:
MNetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedMultiClientRawDatagramBenchmark.cs | 52+++++++++++++++++++++++++++++-----------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedSingleClientRawDatagramBenchmark.cs | 44+++++++++++++++++++++++++-------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderMultiClientBenchmark.cs | 56+++++++++++++++++++++++++++++++-------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderSingleClientBenchmark.cs | 48+++++++++++++++++++++++++++---------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterAsyncBenchmark.cs | 85++++++++++++++++++++++++++++++++++++++++++-------------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterSyncBenchmark.cs | 89+++++++++++++++++++++++++++++++++++++++++--------------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedMultiClientRawStreamBenchmark.cs | 115+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedSingleClientRawStreamBenchmark.cs | 109++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderMultiClientBenchmark.cs | 147++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderSingleClientBenchmark.cs | 140++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterAsyncBenchmark.cs | 99++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
MNetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterSyncBenchmark.cs | 94++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
MNetSharp/NetSharp.Benchmarks/Program.cs | 8++++----
MNetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkReader.cs | 36++++++++++++++++++------------------
MNetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs | 76++++++++++++++++++++++------------------------------------------------------
MNetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs | 1-
MNetSharp/NetSharp/Utils/SlimObjectPool.cs | 14++++++++++++--
17 files changed, 655 insertions(+), 558 deletions(-)

diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedMultiClientRawDatagramBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedMultiClientRawDatagramBenchmark.cs @@ -26,6 +26,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ClientEndPoint); + try { int id = (int) idObj; @@ -39,9 +42,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.Bind(Program.Constants.ClientEndPoint); - using RawDatagramNetworkWriter writer = new RawDatagramNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); lock (typeof(Console)) @@ -74,15 +74,15 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks } ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - rawSocket.Close(); - rawSocket.Dispose(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Client exception: {0}", ex); } + rawSocket.Close(); + rawSocket.Dispose(); + return Task.CompletedTask; } @@ -93,29 +93,35 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[Program.Constants.ClientCount]; - Task[] clientTasks = new Task[Program.Constants.ClientCount]; - for (int i = 0; i < clientTasks.Length; i++) - { - clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); - } - - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); rawSocket.Bind(Program.Constants.ServerEndPoint); - using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); - reader.Start(Program.Constants.ClientCount); + try + { + ClientBandwidths = new double[Program.Constants.ClientCount]; + Task[] clientTasks = new Task[Program.Constants.ClientCount]; + for (int i = 0; i < clientTasks.Length; i++) + { + clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); + } + + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - ServerReadyEvent.Set(); + using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); + reader.Start(Program.Constants.ClientCount); - await Task.WhenAll(clientTasks); + ServerReadyEvent.Set(); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + await Task.WhenAll(clientTasks); - reader.Shutdown(); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedSingleClientRawDatagramBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/CombinedSingleClientRawDatagramBenchmark.cs @@ -26,6 +26,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ClientEndPoint); + try { int id = (int) idObj; @@ -39,9 +42,6 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.Bind(Program.Constants.ClientEndPoint); - using RawDatagramNetworkWriter writer = new RawDatagramNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); lock (typeof(Console)) @@ -74,15 +74,15 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks } ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - rawSocket.Close(); - rawSocket.Dispose(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Client exception: {0}", ex); } + rawSocket.Close(); + rawSocket.Dispose(); + return Task.CompletedTask; } @@ -93,25 +93,31 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[1]; - Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; - - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); rawSocket.Bind(Program.Constants.ServerEndPoint); - using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); - reader.Start(1); + try + { + ClientBandwidths = new double[1]; + Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; + + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + + using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); + reader.Start(1); - ServerReadyEvent.Set(); + ServerReadyEvent.Set(); - await Task.WhenAll(clientTasks); + await Task.WhenAll(clientTasks); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); - reader.Shutdown(); + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderMultiClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderMultiClientBenchmark.cs @@ -27,6 +27,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { + using Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ClientEndPoint); + try { int id = (int) idObj; @@ -38,12 +41,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - clientSocket.Bind(Program.Constants.ClientEndPoint); - lock (typeof(Console)) { - Console.WriteLine($"[Client {id}] Starting client at {clientSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + Console.WriteLine($"[Client {id}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); } benchmarkHelper.ResetStopwatch(); @@ -56,9 +56,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks packetBuffer.CopyTo(sendBuffer, 0); benchmarkHelper.StartStopwatch(); - int sentBytes = clientSocket.SendTo(sendBuffer, remoteEndPoint); + int sentBytes = rawSocket.SendTo(sendBuffer, remoteEndPoint); - int receivedBytes = clientSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint); + int receivedBytes = rawSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint); benchmarkHelper.StopStopwatch(); benchmarkHelper.SnapshotRttStats(); @@ -71,14 +71,14 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks } ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - clientSocket.Close(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Client exception: {0}", ex); } + rawSocket.Close(); + return Task.CompletedTask; } @@ -90,29 +90,35 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[Program.Constants.ClientCount]; - Task[] clientTasks = new Task[Program.Constants.ClientCount]; - for (int i = 0; i < clientTasks.Length; i++) - { - clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); - } - - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); rawSocket.Bind(Program.Constants.ServerEndPoint); - using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); - reader.Start(Program.Constants.ClientCount); + try + { + ClientBandwidths = new double[Program.Constants.ClientCount]; + Task[] clientTasks = new Task[Program.Constants.ClientCount]; + for (int i = 0; i < clientTasks.Length; i++) + { + clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); + } + + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + + using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); + reader.Start(Program.Constants.ClientCount); - ServerReadyEvent.Set(); + ServerReadyEvent.Set(); - await Task.WhenAll(clientTasks); + await Task.WhenAll(clientTasks); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); - reader.Shutdown(); + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderSingleClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkReaderSingleClientBenchmark.cs @@ -27,6 +27,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { + using Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ClientEndPoint); + try { int id = (int) idObj; @@ -38,12 +41,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - clientSocket.Bind(Program.Constants.ClientEndPoint); - lock (typeof(Console)) { - Console.WriteLine($"[Client {id}] Starting client at {clientSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + Console.WriteLine($"[Client {id}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); } benchmarkHelper.ResetStopwatch(); @@ -56,9 +56,9 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks packetBuffer.CopyTo(sendBuffer, 0); benchmarkHelper.StartStopwatch(); - int sentBytes = clientSocket.SendTo(sendBuffer, remoteEndPoint); + int sentBytes = rawSocket.SendTo(sendBuffer, remoteEndPoint); - int receivedBytes = clientSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint); + int receivedBytes = rawSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint); benchmarkHelper.StopStopwatch(); benchmarkHelper.SnapshotRttStats(); @@ -71,14 +71,14 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks } ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - clientSocket.Close(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Client exception: {0}", ex); } + rawSocket.Close(); + return Task.CompletedTask; } @@ -90,25 +90,31 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[1]; - Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; - - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); rawSocket.Bind(Program.Constants.ServerEndPoint); - using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); - reader.Start(1); + try + { + ClientBandwidths = new double[1]; + Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; + + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - ServerReadyEvent.Set(); + using RawDatagramNetworkReader reader = new RawDatagramNetworkReader(ref rawSocket, RequestHandler, defaultRemoteEndPoint, Program.Constants.PacketSize); + reader.Start(1); - await Task.WhenAll(clientTasks); + ServerReadyEvent.Set(); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + await Task.WhenAll(clientTasks); - reader.Shutdown(); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterAsyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterAsyncBenchmark.cs @@ -15,34 +15,33 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks /// <inheritdoc /> public string Name => "Raw Datagram Network Writer Benchmark (Asynchronous)"; - private static Task ServerTask(CancellationToken cancellationToken) + private static Task ServerTask() { + using Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ServerEndPoint); + try { - using Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - server.Bind(Program.Constants.ServerEndPoint); - byte[] transmissionBuffer = new byte[Program.Constants.PacketSize]; EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ServerReadyEvent.Set(); - while (!cancellationToken.IsCancellationRequested) + for (int i = 0; i < Program.Constants.PacketCount; i++) { - server.ReceiveFrom(transmissionBuffer, ref remoteEndPoint); + rawSocket.ReceiveFrom(transmissionBuffer, ref remoteEndPoint); - server.SendTo(transmissionBuffer, remoteEndPoint); + rawSocket.SendTo(transmissionBuffer, remoteEndPoint); } - - server.Close(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Server exception: {0}", ex); } + rawSocket.Close(); + return Task.CompletedTask; } @@ -54,50 +53,56 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ClientEndPoint); - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); + try + { + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - byte[] sendBuffer = new byte[Program.Constants.PacketSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + byte[] sendBuffer = new byte[Program.Constants.PacketSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.Bind(Program.Constants.ClientEndPoint); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using RawDatagramNetworkWriter writer = new RawDatagramNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); + using RawDatagramNetworkWriter writer = new RawDatagramNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); - using CancellationTokenSource serverCts = new CancellationTokenSource(); - Task serverTask = Task.Factory.StartNew(state => ServerTask((CancellationToken) state), serverCts.Token, TaskCreationOptions.LongRunning); + Task serverTask = Task.Factory.StartNew(ServerTask, TaskCreationOptions.LongRunning); - lock (typeof(Console)) - { - Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + lock (typeof(Console)) + { + Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.ResetStopwatch(); + benchmarkHelper.ResetStopwatch(); - ServerReadyEvent.Wait(); + ServerReadyEvent.Wait(); - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); - packetBuffer.CopyTo(sendBuffer, 0); + for (int i = 0; i < Program.Constants.PacketCount; i++) + { + byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); + packetBuffer.CopyTo(sendBuffer, 0); - benchmarkHelper.StartStopwatch(); - int sendResult = await writer.WriteAsync(remoteEndPoint, sendBuffer); + benchmarkHelper.StartStopwatch(); + int sendResult = await writer.WriteAsync(remoteEndPoint, sendBuffer); - int receiveResult = await writer.ReadAsync(remoteEndPoint, receiveBuffer); - benchmarkHelper.StopStopwatch(); + int receiveResult = await writer.ReadAsync(remoteEndPoint, receiveBuffer); + benchmarkHelper.StopStopwatch(); - benchmarkHelper.SnapshotRttStats(); - } + benchmarkHelper.SnapshotRttStats(); + } - benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(0); + benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(0); - serverCts.Cancel(); + serverTask.GetAwaiter().GetResult(); + } + catch (Exception ex) + { + Console.WriteLine("Client exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterSyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Datagram Network Connection Benchmarks/RawDatagramNetworkWriterSyncBenchmark.cs @@ -15,94 +15,97 @@ namespace NetSharp.Benchmarks.Benchmarks.Datagram_Network_Connection_Benchmarks /// <inheritdoc /> public string Name => "Raw Datagram Network Writer Benchmark (Synchronous)"; - private static Task ServerTask(CancellationToken cancellationToken) + private static Task ServerTask() { + using Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ServerEndPoint); + try { - using Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - server.Bind(Program.Constants.ServerEndPoint); - byte[] transmissionBuffer = new byte[Program.Constants.PacketSize]; EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ServerReadyEvent.Set(); - while (!cancellationToken.IsCancellationRequested) + for (int i = 0; i < Program.Constants.PacketCount; i++) { - int received = server.ReceiveFrom(transmissionBuffer, ref remoteEndPoint); + rawSocket.ReceiveFrom(transmissionBuffer, ref remoteEndPoint); - int sent = server.SendTo(transmissionBuffer, remoteEndPoint); + rawSocket.SendTo(transmissionBuffer, remoteEndPoint); } - - server.Close(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Server exception: {0}", ex); } + rawSocket.Close(); + return Task.CompletedTask; } /// <inheritdoc /> - public Task RunAsync() + public async Task RunAsync() { if (Program.Constants.PacketCount > 10_000) { Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rawSocket.Bind(Program.Constants.ClientEndPoint); - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); + try + { + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - byte[] sendBuffer = new byte[Program.Constants.PacketSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + byte[] sendBuffer = new byte[Program.Constants.PacketSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rawSocket.Bind(Program.Constants.ClientEndPoint); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using RawDatagramNetworkWriter writer = new RawDatagramNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); + using RawDatagramNetworkWriter writer = new RawDatagramNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); - using CancellationTokenSource serverCts = new CancellationTokenSource(); - Task serverTask = Task.Factory.StartNew(state => ServerTask((CancellationToken) state), serverCts.Token, TaskCreationOptions.LongRunning); + Task serverTask = Task.Factory.StartNew(ServerTask, TaskCreationOptions.LongRunning); - lock (typeof(Console)) - { - Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + lock (typeof(Console)) + { + Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.ResetStopwatch(); + benchmarkHelper.ResetStopwatch(); - ServerReadyEvent.Wait(); + ServerReadyEvent.Wait(); - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); - packetBuffer.CopyTo(sendBuffer, 0); + for (int i = 0; i < Program.Constants.PacketCount; i++) + { + byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); + packetBuffer.CopyTo(sendBuffer, 0); - benchmarkHelper.StartStopwatch(); - int sendResult = writer.Write(remoteEndPoint, sendBuffer); + benchmarkHelper.StartStopwatch(); + int sendResult = writer.Write(remoteEndPoint, sendBuffer); - int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); - benchmarkHelper.StopStopwatch(); + int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); + benchmarkHelper.StopStopwatch(); - benchmarkHelper.SnapshotRttStats(); - } + benchmarkHelper.SnapshotRttStats(); + } - benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(0); + benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(0); - serverCts.Cancel(); + serverTask.GetAwaiter().GetResult(); + } + catch (Exception ex) + { + Console.WriteLine("Client exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); - - return Task.CompletedTask; } } } \ No newline at end of file diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedMultiClientRawStreamBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedMultiClientRawStreamBenchmark.cs @@ -26,56 +26,65 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { - int id = (int) idObj; + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ClientEndPoint); - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + try + { + int id = (int) idObj; - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - byte[] sendBuffer = new byte[Program.Constants.PacketSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + byte[] sendBuffer = new byte[Program.Constants.PacketSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.Bind(Program.Constants.ClientEndPoint); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); + using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); - lock (typeof(Console)) - { - Console.WriteLine($"[Client {id}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + lock (typeof(Console)) + { + Console.WriteLine($"[Client {id}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.ResetStopwatch(); + benchmarkHelper.ResetStopwatch(); - ServerReadyEvent.Wait(); - rawSocket.Connect(Program.Constants.ServerEndPoint); + ServerReadyEvent.Wait(); + rawSocket.Connect(Program.Constants.ServerEndPoint); - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})"); - packetBuffer.CopyTo(sendBuffer, 0); + for (int i = 0; i < Program.Constants.PacketCount; i++) + { + byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})"); + packetBuffer.CopyTo(sendBuffer, 0); - benchmarkHelper.StartStopwatch(); - int sendResult = writer.Write(remoteEndPoint, sendBuffer); + benchmarkHelper.StartStopwatch(); + int sendResult = writer.Write(remoteEndPoint, sendBuffer); - int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); - benchmarkHelper.StopStopwatch(); + int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); + benchmarkHelper.StopStopwatch(); - benchmarkHelper.SnapshotRttStats(); - } + benchmarkHelper.SnapshotRttStats(); + } + + lock (typeof(Console)) + { + benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(id); + } + + ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - lock (typeof(Console)) + rawSocket.Disconnect(false); + rawSocket.Shutdown(SocketShutdown.Both); + } + catch (Exception ex) { - benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(id); + Console.WriteLine("Client exception: {0}", ex); } - ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - rawSocket.Shutdown(SocketShutdown.Both); - rawSocket.Disconnect(false); rawSocket.Close(); rawSocket.Dispose(); @@ -89,30 +98,38 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[Program.Constants.ClientCount]; - Task[] clientTasks = new Task[Program.Constants.ClientCount]; - for (int i = 0; i < clientTasks.Length; i++) + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ServerEndPoint); + + try { - clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); - } + ClientBandwidths = new double[Program.Constants.ClientCount]; + Task[] clientTasks = new Task[Program.Constants.ClientCount]; + for (int i = 0; i < clientTasks.Length; i++) + { + clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); + } - EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); + EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - rawSocket.Bind(Program.Constants.ServerEndPoint); - rawSocket.Listen(Program.Constants.ClientCount); + rawSocket.Listen(Program.Constants.ClientCount); - using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); - reader.Start(Program.Constants.ClientCount); + using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); + reader.Start(Program.Constants.ClientCount); - ServerReadyEvent.Set(); + ServerReadyEvent.Set(); - await Task.WhenAll(clientTasks); + await Task.WhenAll(clientTasks); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); - reader.Shutdown(); + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedSingleClientRawStreamBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/CombinedSingleClientRawStreamBenchmark.cs @@ -25,56 +25,65 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { - int id = (int) idObj; + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ClientEndPoint); - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + try + { + int id = (int) idObj; - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - byte[] sendBuffer = new byte[Program.Constants.PacketSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + byte[] sendBuffer = new byte[Program.Constants.PacketSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.Bind(Program.Constants.ClientEndPoint); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); + using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); - lock (typeof(Console)) - { - Console.WriteLine($"[Client {id}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + lock (typeof(Console)) + { + Console.WriteLine($"[Client {id}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.ResetStopwatch(); + benchmarkHelper.ResetStopwatch(); - ServerReadyEvent.Wait(); - rawSocket.Connect(Program.Constants.ServerEndPoint); + ServerReadyEvent.Wait(); + rawSocket.Connect(Program.Constants.ServerEndPoint); - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})"); - packetBuffer.CopyTo(sendBuffer, 0); + for (int i = 0; i < Program.Constants.PacketCount; i++) + { + byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})"); + packetBuffer.CopyTo(sendBuffer, 0); - benchmarkHelper.StartStopwatch(); - int sendResult = writer.Write(remoteEndPoint, sendBuffer); + benchmarkHelper.StartStopwatch(); + int sendResult = writer.Write(remoteEndPoint, sendBuffer); - int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); - benchmarkHelper.StopStopwatch(); + int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); + benchmarkHelper.StopStopwatch(); - benchmarkHelper.SnapshotRttStats(); - } + benchmarkHelper.SnapshotRttStats(); + } + + lock (typeof(Console)) + { + benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(id); + } + + ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - lock (typeof(Console)) + rawSocket.Disconnect(false); + rawSocket.Shutdown(SocketShutdown.Both); + } + catch (Exception ex) { - benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(id); + Console.WriteLine("Client exception: {0}", ex); } - ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - rawSocket.Shutdown(SocketShutdown.Both); - rawSocket.Disconnect(false); rawSocket.Close(); rawSocket.Dispose(); @@ -88,26 +97,34 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[1]; - Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; - - EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ServerEndPoint); - rawSocket.Listen(1); - using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); - reader.Start(1); + try + { + ClientBandwidths = new double[1]; + Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; + + EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); - ServerReadyEvent.Set(); + rawSocket.Listen(1); - await clientTasks[0]; + using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); + reader.Start(1); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths[0]:F3}"); + ServerReadyEvent.Set(); - reader.Shutdown(); + await clientTasks[0]; + + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths[0]:F3}"); + + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderMultiClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderMultiClientBenchmark.cs @@ -27,77 +27,85 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { - int id = (int) idObj; - - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - - byte[] sendBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; - byte[] packetBuffer = new byte[Program.Constants.PacketSize]; - - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); clientSocket.Bind(Program.Constants.ClientEndPoint); - lock (typeof(Console)) + try { - Console.WriteLine($"[Client {id}] Starting client at {clientSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + int id = (int) idObj; - benchmarkHelper.ResetStopwatch(); + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - ServerReadyEvent.Wait(); - clientSocket.Connect(Program.Constants.ServerEndPoint); + byte[] sendBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; + byte[] packetBuffer = new byte[Program.Constants.PacketSize]; - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})").CopyTo(packetBuffer, 0); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + + lock (typeof(Console)) + { + Console.WriteLine($"[Client {id}] Starting client at {clientSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - RawStreamPacketHeader streamPacketHeader = new RawStreamPacketHeader(Program.Constants.PacketSize); - RawStreamPacket.Serialise(sendBuffer, in streamPacketHeader, packetBuffer); + benchmarkHelper.ResetStopwatch(); - benchmarkHelper.StartStopwatch(); + ServerReadyEvent.Wait(); + clientSocket.Connect(Program.Constants.ServerEndPoint); - int totalSent = 0; - do + for (int i = 0; i < Program.Constants.PacketCount; i++) { - totalSent += clientSocket.Send(sendBuffer, totalSent, sendBuffer.Length - totalSent, - SocketFlags.None); - } while (totalSent != 0 && totalSent < sendBuffer.Length); + Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})").CopyTo(packetBuffer, 0); - if (totalSent == 0) - { - break; - } + RawStreamPacketHeader streamPacketHeader = new RawStreamPacketHeader(Program.Constants.PacketSize); + RawStreamPacket.Serialise(sendBuffer, in streamPacketHeader, packetBuffer); - int totalReceived = 0; - do - { - totalReceived += clientSocket.Receive(receiveBuffer, totalReceived, receiveBuffer.Length - totalReceived, - SocketFlags.None); - } while (totalReceived != 0 && totalReceived < receiveBuffer.Length); + benchmarkHelper.StartStopwatch(); + + int totalSent = 0; + do + { + totalSent += clientSocket.Send(sendBuffer, totalSent, sendBuffer.Length - totalSent, + SocketFlags.None); + } while (totalSent != 0 && totalSent < sendBuffer.Length); + + if (totalSent == 0) + { + break; + } + + int totalReceived = 0; + do + { + totalReceived += clientSocket.Receive(receiveBuffer, totalReceived, receiveBuffer.Length - totalReceived, + SocketFlags.None); + } while (totalReceived != 0 && totalReceived < receiveBuffer.Length); + + if (totalReceived == 0) + { + break; + } - if (totalReceived == 0) + benchmarkHelper.StopStopwatch(); + + benchmarkHelper.SnapshotRttStats(); + } + + lock (typeof(Console)) { - break; + benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(id); } - benchmarkHelper.StopStopwatch(); + ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.SnapshotRttStats(); + clientSocket.Shutdown(SocketShutdown.Both); } - - lock (typeof(Console)) + catch (Exception ex) { - benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(id); + Console.WriteLine("Client exception: {0}", ex); } - ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - clientSocket.Shutdown(SocketShutdown.Both); - clientSocket.Disconnect(false); clientSocket.Close(); return Task.CompletedTask; @@ -111,30 +119,39 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[Program.Constants.ClientCount]; - Task[] clientTasks = new Task[Program.Constants.ClientCount]; - for (int i = 0; i < clientTasks.Length; i++) + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ServerEndPoint); + + try { - clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); - } + ClientBandwidths = new double[Program.Constants.ClientCount]; + Task[] clientTasks = new Task[Program.Constants.ClientCount]; + for (int i = 0; i < clientTasks.Length; i++) + { + clientTasks[i] = Task.Factory.StartNew(BenchmarkClientTask, i, TaskCreationOptions.LongRunning); + } - EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); + EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - rawSocket.Bind(Program.Constants.ServerEndPoint); - rawSocket.Listen(Program.Constants.ClientCount); + rawSocket.Listen(Program.Constants.ClientCount); - using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); - reader.Start(Program.Constants.ClientCount); + using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); + reader.Start(Program.Constants.ClientCount); - ServerReadyEvent.Set(); + ServerReadyEvent.Set(); - await Task.WhenAll(clientTasks); + await Task.WhenAll(clientTasks); - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths.Sum():F3}"); - reader.Shutdown(); + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + throw; + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderSingleClientBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkReaderSingleClientBenchmark.cs @@ -26,77 +26,85 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks private Task BenchmarkClientTask(object idObj) { - int id = (int) idObj; - - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - - byte[] sendBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; - byte[] packetBuffer = new byte[Program.Constants.PacketSize]; - - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); clientSocket.Bind(Program.Constants.ClientEndPoint); - lock (typeof(Console)) + try { - Console.WriteLine($"[Client {id}] Starting client at {clientSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + int id = (int) idObj; - benchmarkHelper.ResetStopwatch(); + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - ServerReadyEvent.Wait(); - clientSocket.Connect(Program.Constants.ServerEndPoint); + byte[] sendBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize + RawStreamPacketHeader.TotalSize]; + byte[] packetBuffer = new byte[Program.Constants.PacketSize]; - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})").CopyTo(packetBuffer, 0); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - RawStreamPacketHeader streamPacketHeader = new RawStreamPacketHeader(Program.Constants.PacketSize); - RawStreamPacket.Serialise(sendBuffer, in streamPacketHeader, packetBuffer); + lock (typeof(Console)) + { + Console.WriteLine($"[Client {id}] Starting client at {clientSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.StartStopwatch(); + benchmarkHelper.ResetStopwatch(); - int totalSent = 0; - do - { - totalSent += clientSocket.Send(sendBuffer, totalSent, sendBuffer.Length - totalSent, - SocketFlags.None); - } while (totalSent != 0 && totalSent < sendBuffer.Length); + ServerReadyEvent.Wait(); + clientSocket.Connect(Program.Constants.ServerEndPoint); - if (totalSent == 0) + for (int i = 0; i < Program.Constants.PacketCount; i++) { - break; - } + Program.Constants.ServerEncoding.GetBytes($"[Client {id}] Hello World! (Packet {i})").CopyTo(packetBuffer, 0); - int totalReceived = 0; - do - { - totalReceived += clientSocket.Receive(receiveBuffer, totalReceived, receiveBuffer.Length - totalReceived, - SocketFlags.None); - } while (totalReceived != 0 && totalReceived < receiveBuffer.Length); + RawStreamPacketHeader streamPacketHeader = new RawStreamPacketHeader(Program.Constants.PacketSize); + RawStreamPacket.Serialise(sendBuffer, in streamPacketHeader, packetBuffer); + + benchmarkHelper.StartStopwatch(); + + int totalSent = 0; + do + { + totalSent += clientSocket.Send(sendBuffer, totalSent, sendBuffer.Length - totalSent, + SocketFlags.None); + } while (totalSent != 0 && totalSent < sendBuffer.Length); + + if (totalSent == 0) + { + break; + } + + int totalReceived = 0; + do + { + totalReceived += clientSocket.Receive(receiveBuffer, totalReceived, receiveBuffer.Length - totalReceived, + SocketFlags.None); + } while (totalReceived != 0 && totalReceived < receiveBuffer.Length); - if (totalReceived == 0) + if (totalReceived == 0) + { + break; + } + + benchmarkHelper.StopStopwatch(); + + benchmarkHelper.SnapshotRttStats(); + } + + lock (typeof(Console)) { - break; + benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(id); } - benchmarkHelper.StopStopwatch(); + ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.SnapshotRttStats(); + clientSocket.Shutdown(SocketShutdown.Both); } - - lock (typeof(Console)) + catch (Exception ex) { - benchmarkHelper.PrintBandwidthStats(id, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(id); + Console.WriteLine("Client exception: {0}", ex); } - ClientBandwidths[id] = benchmarkHelper.CalcBandwidth(Program.Constants.PacketCount, Program.Constants.PacketSize); - - clientSocket.Shutdown(SocketShutdown.Both); - clientSocket.Disconnect(false); clientSocket.Close(); return Task.CompletedTask; @@ -110,26 +118,34 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - ClientBandwidths = new double[1]; - Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; - - EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); rawSocket.Bind(Program.Constants.ServerEndPoint); - rawSocket.Listen(1); - using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); - reader.Start(1); + try + { + ClientBandwidths = new double[1]; + Task[] clientTasks = new Task[] { Task.Factory.StartNew(BenchmarkClientTask, 0, TaskCreationOptions.LongRunning) }; + + EndPoint defaultEndPoint = new IPEndPoint(IPAddress.Any, 0); + + rawSocket.Listen(1); + + using RawStreamNetworkReader reader = new RawStreamNetworkReader(ref rawSocket, RequestHandler, defaultEndPoint, Program.Constants.PacketSize); + reader.Start(1); - ServerReadyEvent.Set(); + ServerReadyEvent.Set(); - await clientTasks[0]; + await clientTasks[0]; - Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths[0]:F3}"); + Console.WriteLine($"Total estimated bandwidth: {ClientBandwidths[0]:F3}"); - reader.Shutdown(); + reader.Shutdown(); + } + catch (Exception ex) + { + Console.WriteLine("Server exception: {0}", ex); + } rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterAsyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterAsyncBenchmark.cs @@ -15,24 +15,26 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks /// <inheritdoc /> public string Name => "Raw Stream Network Writer Benchmark (Asynchronous)"; - private static Task ServerTask(CancellationToken cancellationToken) + private static Task ServerTask() { + using Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ServerEndPoint); + try { - using Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - server.Bind(Program.Constants.ServerEndPoint); - + // all the headers should have the same packet size, so will fit in the transmission buffer RawStreamPacketHeader archetypalHeader = new RawStreamPacketHeader(Program.Constants.PacketSize); byte[] transmissionBuffer = new byte[RawStreamPacket.TotalPacketSize(in archetypalHeader)]; - server.Listen(1); + rawSocket.Listen(1); ServerReadyEvent.Set(); - Socket clientSocket = server.Accept(); + using Socket clientSocket = rawSocket.Accept(); + clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); - while (!cancellationToken.IsCancellationRequested) + for (int i = 0; i < Program.Constants.PacketCount; i++) { int expectedBytes = transmissionBuffer.Length; @@ -40,7 +42,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks do { receivedBytes += clientSocket.Receive(transmissionBuffer, receivedBytes, expectedBytes - receivedBytes, SocketFlags.None); - } while (receivedBytes != 0 && receivedBytes < expectedBytes); + } while (receivedBytes < expectedBytes && receivedBytes > 0); if (receivedBytes == 0) { @@ -51,7 +53,7 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks do { sentBytes += clientSocket.Send(transmissionBuffer, sentBytes, expectedBytes - sentBytes, SocketFlags.None); - } while (sentBytes != 0 && sentBytes < expectedBytes); + } while (sentBytes < expectedBytes && sentBytes > 0); if (sentBytes == 0) { @@ -59,13 +61,17 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks } } - server.Close(); + clientSocket.Disconnect(false); + clientSocket.Shutdown(SocketShutdown.Both); + clientSocket.Close(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Server exception: {0}", ex); } + rawSocket.Close(); + return Task.CompletedTask; } @@ -77,54 +83,59 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ClientEndPoint); - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); + try + { + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - byte[] sendBuffer = new byte[Program.Constants.PacketSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + byte[] sendBuffer = new byte[Program.Constants.PacketSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.Bind(Program.Constants.ClientEndPoint); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); + using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); - using CancellationTokenSource serverCts = new CancellationTokenSource(); - Task serverTask = Task.Factory.StartNew(state => ServerTask((CancellationToken) state), serverCts.Token, TaskCreationOptions.LongRunning); + Task serverTask = Task.Factory.StartNew(ServerTask, TaskCreationOptions.LongRunning); - lock (typeof(Console)) - { - Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + lock (typeof(Console)) + { + Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.ResetStopwatch(); + benchmarkHelper.ResetStopwatch(); - ServerReadyEvent.Wait(); - rawSocket.Connect(Program.Constants.ServerEndPoint); + ServerReadyEvent.Wait(); + rawSocket.Connect(Program.Constants.ServerEndPoint); - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); - packetBuffer.CopyTo(sendBuffer, 0); + for (int i = 0; i < Program.Constants.PacketCount; i++) + { + byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); + packetBuffer.CopyTo(sendBuffer, 0); - benchmarkHelper.StartStopwatch(); - int sendResult = await writer.WriteAsync(remoteEndPoint, sendBuffer); + benchmarkHelper.StartStopwatch(); + int sendResult = await writer.WriteAsync(remoteEndPoint, sendBuffer); - int receiveResult = await writer.ReadAsync(remoteEndPoint, receiveBuffer); - benchmarkHelper.StopStopwatch(); + int receiveResult = await writer.ReadAsync(remoteEndPoint, receiveBuffer); + benchmarkHelper.StopStopwatch(); - benchmarkHelper.SnapshotRttStats(); - } + benchmarkHelper.SnapshotRttStats(); + } - benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(0); + benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(0); - serverCts.Cancel(); + rawSocket.Shutdown(SocketShutdown.Both); + } + catch (Exception ex) + { + Console.WriteLine("Client exception: {0}", ex); + } - rawSocket.Shutdown(SocketShutdown.Both); - rawSocket.Disconnect(false); rawSocket.Close(); rawSocket.Dispose(); } diff --git a/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterSyncBenchmark.cs b/NetSharp/NetSharp.Benchmarks/Benchmarks/Stream Network Connection Benchmarks/RawStreamNetworkWriterSyncBenchmark.cs @@ -15,25 +15,26 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks /// <inheritdoc /> public string Name => "Raw Stream Network Writer Benchmark (Synchronous)"; - private static Task ServerTask(CancellationToken cancellationToken) + private static Task ServerTask() { + using Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ServerEndPoint); + try { - using Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - server.Bind(Program.Constants.ServerEndPoint); - // all the headers should have the same packet size, so will fit in the transmission buffer RawStreamPacketHeader archetypalHeader = new RawStreamPacketHeader(Program.Constants.PacketSize); byte[] transmissionBuffer = new byte[RawStreamPacket.TotalPacketSize(in archetypalHeader)]; - server.Listen(1); + rawSocket.Listen(1); ServerReadyEvent.Set(); - Socket clientSocket = server.Accept(); + using Socket clientSocket = rawSocket.Accept(); + clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); - while (!cancellationToken.IsCancellationRequested) + for (int i = 0; i < Program.Constants.PacketCount; i++) { int expectedBytes = transmissionBuffer.Length; @@ -60,13 +61,17 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks } } - server.Close(); + clientSocket.Disconnect(false); + clientSocket.Shutdown(SocketShutdown.Both); + clientSocket.Close(); } catch (Exception ex) { - Console.WriteLine(ex); + Console.WriteLine("Server exception: {0}", ex); } + rawSocket.Close(); + return Task.CompletedTask; } @@ -78,54 +83,59 @@ namespace NetSharp.Benchmarks.Benchmarks.Stream_Network_Connection_Benchmarks Console.WriteLine($"{Program.Constants.PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!"); } - EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + rawSocket.Bind(Program.Constants.ClientEndPoint); - BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); + try + { + EndPoint defaultRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); - byte[] sendBuffer = new byte[Program.Constants.PacketSize]; - byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; + BenchmarkHelper benchmarkHelper = new BenchmarkHelper(); - EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; + byte[] sendBuffer = new byte[Program.Constants.PacketSize]; + byte[] receiveBuffer = new byte[Program.Constants.PacketSize]; - Socket rawSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - rawSocket.Bind(Program.Constants.ClientEndPoint); + EndPoint remoteEndPoint = Program.Constants.ServerEndPoint; - using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); + using RawStreamNetworkWriter writer = new RawStreamNetworkWriter(ref rawSocket, defaultRemoteEndPoint, Program.Constants.PacketSize); - using CancellationTokenSource serverCts = new CancellationTokenSource(); - Task serverTask = Task.Factory.StartNew(state => ServerTask((CancellationToken) state), serverCts.Token, TaskCreationOptions.LongRunning); + Task serverTask = Task.Factory.StartNew(ServerTask, TaskCreationOptions.LongRunning); - lock (typeof(Console)) - { - Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); - } + lock (typeof(Console)) + { + Console.WriteLine($"[Client {0}] Starting client at {rawSocket.LocalEndPoint}; sending messages to {remoteEndPoint}"); + } - benchmarkHelper.ResetStopwatch(); + benchmarkHelper.ResetStopwatch(); - ServerReadyEvent.Wait(); - rawSocket.Connect(Program.Constants.ServerEndPoint); + ServerReadyEvent.Wait(); + rawSocket.Connect(Program.Constants.ServerEndPoint); - for (int i = 0; i < Program.Constants.PacketCount; i++) - { - byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); - packetBuffer.CopyTo(sendBuffer, 0); + for (int i = 0; i < Program.Constants.PacketCount; i++) + { + byte[] packetBuffer = Program.Constants.ServerEncoding.GetBytes($"[Client 0] Hello World! (Packet {i})"); + packetBuffer.CopyTo(sendBuffer, 0); - benchmarkHelper.StartStopwatch(); - int sendResult = writer.Write(remoteEndPoint, sendBuffer); + benchmarkHelper.StartStopwatch(); + int sendResult = writer.Write(remoteEndPoint, sendBuffer); - int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); - benchmarkHelper.StopStopwatch(); + int receiveResult = writer.Read(ref remoteEndPoint, receiveBuffer); + benchmarkHelper.StopStopwatch(); - benchmarkHelper.SnapshotRttStats(); - } + benchmarkHelper.SnapshotRttStats(); + } - benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); - benchmarkHelper.PrintRttStats(0); + benchmarkHelper.PrintBandwidthStats(0, Program.Constants.PacketCount, Program.Constants.PacketSize); + benchmarkHelper.PrintRttStats(0); - serverCts.Cancel(); + rawSocket.Shutdown(SocketShutdown.Both); + } + catch (Exception ex) + { + Console.WriteLine("Client exception: {0}", ex); + } - rawSocket.Shutdown(SocketShutdown.Both); - rawSocket.Disconnect(false); rawSocket.Close(); rawSocket.Dispose(); diff --git a/NetSharp/NetSharp.Benchmarks/Program.cs b/NetSharp/NetSharp.Benchmarks/Program.cs @@ -112,14 +112,14 @@ namespace NetSharp.Benchmarks public static class Constants { - private const int DefaultExamplePort = 44231; - private static readonly IPAddress DefaultExampleAddress = IPAddress.Loopback; + private const int DefaultPort = 44231; + private static readonly IPAddress DefaultAddress = IPAddress.Loopback; public const int PacketSize = 8192, PacketCount = 100_000, ClientCount = 8; - public static readonly EndPoint ClientEndPoint = new IPEndPoint(DefaultExampleAddress, 0); + public static readonly EndPoint ClientEndPoint = new IPEndPoint(DefaultAddress, 0); public static readonly Encoding ServerEncoding = Encoding.UTF8; - public static readonly EndPoint ServerEndPoint = new IPEndPoint(DefaultExampleAddress, DefaultExamplePort); + public static readonly EndPoint ServerEndPoint = new IPEndPoint(DefaultAddress, DefaultPort); } } } \ No newline at end of file diff --git a/NetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkReader.cs b/NetSharp/NetSharp/Raw/Datagram/RawDatagramNetworkReader.cs @@ -73,7 +73,7 @@ namespace NetSharp.Raw.Datagram { args.SetBuffer(responseBuffer, 0, datagramSize); - SendTo(args); + StartSendTo(args); return; } @@ -92,7 +92,7 @@ namespace NetSharp.Raw.Datagram } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConfigureReceiveFrom(SocketAsyncEventArgs args) + private void ConfigureAsyncReceiveFrom(SocketAsyncEventArgs args) { byte[] receiveBuffer = BufferPool.Rent(datagramSize); args.SetBuffer(receiveBuffer, 0, datagramSize); @@ -114,7 +114,21 @@ namespace NetSharp.Raw.Datagram } } - private void ReceiveFrom(SocketAsyncEventArgs args) + private void StartDefaultReceiveFrom() + { + if (ShutdownToken.IsCancellationRequested) + { + return; + } + + SocketAsyncEventArgs args = ArgsPool.Rent(); + + ConfigureAsyncReceiveFrom(args); + + StartReceiveFrom(args); + } + + private void StartReceiveFrom(SocketAsyncEventArgs args) { if (ShutdownToken.IsCancellationRequested) { @@ -131,7 +145,7 @@ namespace NetSharp.Raw.Datagram CompleteReceiveFrom(args); } - private void SendTo(SocketAsyncEventArgs args) + private void StartSendTo(SocketAsyncEventArgs args) { if (ShutdownToken.IsCancellationRequested) { @@ -147,20 +161,6 @@ namespace NetSharp.Raw.Datagram CompleteSendTo(args); } - private void StartDefaultReceiveFrom() - { - if (ShutdownToken.IsCancellationRequested) - { - return; - } - - SocketAsyncEventArgs args = ArgsPool.Rent(); - - ConfigureReceiveFrom(args); - - ReceiveFrom(args); - } - /// <inheritdoc /> protected override bool CanReuseStateObject(ref SocketAsyncEventArgs instance) { diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkReader.cs @@ -56,11 +56,12 @@ namespace NetSharp.Raw.Stream { BufferPool.Return(args.Buffer, true); - Socket clientSocket = args.AcceptSocket; + Socket serversideClient = args.AcceptSocket; - clientSocket.Shutdown(SocketShutdown.Both); - clientSocket.Close(); - clientSocket.Dispose(); + serversideClient.Disconnect(false); + serversideClient.Shutdown(SocketShutdown.Both); + serversideClient.Close(); + serversideClient.Dispose(); ArgsPool.Return(args); } @@ -70,13 +71,16 @@ namespace NetSharp.Raw.Stream switch (args.SocketError) { case SocketError.Success: + // ensure that the serverside client socket will be successfully, gracefully shutdown after the conection ends + args.AcceptSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); + // the buffer is set to allow a simpler ConfigureReceiveHeader() implemetation. Since returning an empty buffer is ignored in the // array pool, this allows us to just return the last assigned buffer in the ConfigureXXX() method to the pool (this means that // usually we will usually be returning the ResponseDataBuffer). args.SetBuffer(Array.Empty<byte>(), 0, 0); ConfigureAsyncReceiveHeader(args); - StartReceive(args); + StartOrContinueReceive(args); break; default: @@ -140,7 +144,7 @@ namespace NetSharp.Raw.Stream { case true: ConfigureAsyncSendPacket(args, ref responseBuffer, in responseHeader, responseBufferMemory); - StartSend(args); + StartOrContinueSend(args); break; case false: @@ -149,7 +153,7 @@ namespace NetSharp.Raw.Stream BufferPool.Return(responseBuffer, true); ConfigureAsyncReceiveHeader(args); - StartReceive(args); + StartOrContinueReceive(args); break; } } @@ -157,7 +161,7 @@ namespace NetSharp.Raw.Stream { args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); - ContinueReceive(args); + StartOrContinueReceive(args); } else if (receivedBytes == 0) // connection is dead { @@ -179,13 +183,13 @@ namespace NetSharp.Raw.Stream RawStreamPacketHeader header = RawStreamPacketHeader.Deserialise(in headerBuffer); ConfigureAsyncReceiveData(args, in header); - StartReceive(args); + StartOrContinueReceive(args); } else if (0 < totalReceivedBytes && totalReceivedBytes < expectedBytes) // transmission not complete { args.SetBuffer(totalReceivedBytes, expectedBytes - totalReceivedBytes); - ContinueReceive(args); + StartOrContinueReceive(args); } else if (receivedBytes == 0) // connection is dead { @@ -208,13 +212,13 @@ namespace NetSharp.Raw.Stream if (totalSentBytes == expectedBytes) // transmission complete { ConfigureAsyncReceiveHeader(args); - StartReceive(args); + StartOrContinueReceive(args); } else if (0 < totalSentBytes && totalSentBytes < expectedBytes) // transmission not complete { args.SetBuffer(totalSentBytes, expectedBytes - totalSentBytes); - ContinueSend(args); + StartOrContinueSend(args); } else if (sentBytes == 0) // connection is dead { @@ -260,42 +264,6 @@ namespace NetSharp.Raw.Stream args.UserToken = new PacketWriteToken(totalPacketSize); } - private void ContinueReceive(SocketAsyncEventArgs args) - { - if (ShutdownToken.IsCancellationRequested) - { - CloseClientConnection(args); - return; - } - - Socket clientSocket = args.AcceptSocket; - - if (clientSocket.ReceiveAsync(args)) - { - return; - } - - CompleteReceive(args); - } - - private void ContinueSend(SocketAsyncEventArgs args) - { - if (ShutdownToken.IsCancellationRequested) - { - CloseClientConnection(args); - return; - } - - Socket clientSocket = args.AcceptSocket; - - if (clientSocket.SendAsync(args)) - { - return; - } - - CompleteSend(args); - } - private void HandleIoCompleted(object sender, SocketAsyncEventArgs args) { switch (args.LastOperation) @@ -342,7 +310,7 @@ namespace NetSharp.Raw.Stream StartAccept(args); } - private void StartReceive(SocketAsyncEventArgs args) + private void StartOrContinueReceive(SocketAsyncEventArgs args) { if (ShutdownToken.IsCancellationRequested) { @@ -350,9 +318,9 @@ namespace NetSharp.Raw.Stream return; } - Socket clientSocket = args.AcceptSocket; + Socket serversideClient = args.AcceptSocket; - if (clientSocket.ReceiveAsync(args)) + if (serversideClient.ReceiveAsync(args)) { return; } @@ -360,7 +328,7 @@ namespace NetSharp.Raw.Stream CompleteReceive(args); } - private void StartSend(SocketAsyncEventArgs args) + private void StartOrContinueSend(SocketAsyncEventArgs args) { if (ShutdownToken.IsCancellationRequested) { @@ -368,9 +336,9 @@ namespace NetSharp.Raw.Stream return; } - Socket clientSocket = args.AcceptSocket; + Socket serversideClient = args.AcceptSocket; - if (clientSocket.SendAsync(args)) + if (serversideClient.SendAsync(args)) { return; } diff --git a/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs b/NetSharp/NetSharp/Raw/Stream/RawStreamNetworkWriter.cs @@ -181,7 +181,6 @@ namespace NetSharp.Raw.Stream args.SetBuffer(pendingPacketDataBuffer, 0, receivedPacketHeader.DataSize); - // TODO add transmission state token args.UserToken = new PacketReadToken(receivedPacketHeader.DataSize, receivedPacketHeader, in userDataBuffer, tcs); } diff --git a/NetSharp/NetSharp/Utils/SlimObjectPool.cs b/NetSharp/NetSharp/Utils/SlimObjectPool.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Runtime.CompilerServices; namespace NetSharp.Utils { @@ -122,9 +123,12 @@ namespace NetSharp.Utils /// <returns> /// The <typeparamref name="T" /> instance which was fetched from the pool. /// </returns> + [MethodImpl(MethodImplOptions.Synchronized)] public T Rent() { - return objectBuffer.TryTake(out T result) ? result : createObjectDelegate(); + bool rentedInstance = objectBuffer.TryTake(out T result); + + return rentedInstance ? result : createObjectDelegate(); } /// <summary> @@ -133,13 +137,19 @@ namespace NetSharp.Utils /// <param name="instance"> /// The previously leased instance which should be returned. /// </param> + [MethodImpl(MethodImplOptions.Synchronized)] public void Return(T instance) { if (canObjectBeRebufferedPredicate(ref instance)) { resetObjectDelegate(ref instance); - objectBuffer.TryAdd(instance); + bool couldRebuffer = false; + + while (!couldRebuffer) + { + couldRebuffer = objectBuffer.TryAdd(instance); + } } else {