From cbfab2ee63ec4bd969583a85b24c2a2b28bfa2c1 Mon Sep 17 00:00:00 2001 From: EonaCat Date: Wed, 1 Oct 2025 21:26:56 +0200 Subject: [PATCH] Added Proxy Tester --- .../EonaCat.Network.Tester.csproj | 2 +- EonaCat.Network.Tester/Program.cs | 139 ++++++++++++++---- EonaCat.Network.Tester/TestModule.cs | 16 -- .../ProxyTester.Client/ProxyTester.Client.sln | 31 ++++ .../ProxyTester.Client/Program.cs | 86 +++++++++++ .../ProxyTester.Client.csproj | 20 +++ .../ProxyTester.Server/Program.cs | 95 ++++++++++++ .../ProxyTester.Server.csproj | 20 +++ 8 files changed, 364 insertions(+), 45 deletions(-) delete mode 100644 EonaCat.Network.Tester/TestModule.cs create mode 100644 ProxyTester/ProxyTester.Client/ProxyTester.Client.sln create mode 100644 ProxyTester/ProxyTester.Client/ProxyTester.Client/Program.cs create mode 100644 ProxyTester/ProxyTester.Client/ProxyTester.Client/ProxyTester.Client.csproj create mode 100644 ProxyTester/ProxyTester.Server/ProxyTester.Server/Program.cs create mode 100644 ProxyTester/ProxyTester.Server/ProxyTester.Server/ProxyTester.Server.csproj diff --git a/EonaCat.Network.Tester/EonaCat.Network.Tester.csproj b/EonaCat.Network.Tester/EonaCat.Network.Tester.csproj index 3b0107d..20bac56 100644 --- a/EonaCat.Network.Tester/EonaCat.Network.Tester.csproj +++ b/EonaCat.Network.Tester/EonaCat.Network.Tester.csproj @@ -8,7 +8,7 @@ - + diff --git a/EonaCat.Network.Tester/Program.cs b/EonaCat.Network.Tester/Program.cs index 88cd9bb..98081ba 100644 --- a/EonaCat.Network.Tester/Program.cs +++ b/EonaCat.Network.Tester/Program.cs @@ -1,11 +1,13 @@ // This file is part of the EonaCat project(s) which is released under the Apache License. // See the LICENSE file or go to https://EonaCat.com/License for full license details. +using System.Net; using System.Net.Security; using System.Reflection; using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; +using System.Text; using EonaCat.WebSockets; internal class Program @@ -18,44 +20,125 @@ internal class Program // Menu loop while (true) { - Console.WriteLine("0. Create a HTTPS certificate"); - Console.WriteLine("1. Start the server and client"); - Console.WriteLine("2. Send Message"); - Console.WriteLine("3. Quit"); - - var choice = Console.ReadLine(); - - switch (choice) + try { - case "0": - CreateCertificate(); - break; + Console.WriteLine("0. Create a HTTPS certificate"); + Console.WriteLine("1. Start the server and client"); + Console.WriteLine("2. Send Message"); + Console.WriteLine("3. Tcp Server and Tcp Client Test With SSL"); + Console.WriteLine("4. Quit"); - case "1": - await CreateServerAndClientAsync().ConfigureAwait(false); - break; + var choice = Console.ReadLine(); - case "2": - if (_client != null) - { - Console.Write("Enter message: "); - var message = Console.ReadLine(); - await _client.SendTextAsync(message).ConfigureAwait(false); - } + switch (choice) + { + case "0": + CreateCertificate(); + break; - break; + case "1": + await CreateServerAndClientAsync().ConfigureAwait(false); + break; - case "3": - _client?.CloseAsync().ConfigureAwait(false); - return; + case "2": + if (_client != null) + { + Console.Write("Enter message: "); + var message = Console.ReadLine(); + await _client.SendTextAsync(message).ConfigureAwait(false); + } - default: - Console.WriteLine("Invalid choice. Try again."); - break; + break; + + case "3": + await CreateTcpClientAndServerTestWithSSL().ConfigureAwait(false); + break; + + case "4": + _client?.CloseAsync().ConfigureAwait(false); + return; + + default: + Console.WriteLine("Invalid choice. Try again."); + break; + } + } + catch (Exception ex) + { + Console.WriteLine($"Exception at: {DateTime.Now} {ex.Message}"); + Console.ReadKey(); } } } + private static async Task CreateTcpClientAndServerTestWithSSL() + { + var certificatePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "localhost.pfx"); + var certificatePassword = ""; + var loadedCertificate = new X509Certificate2(certificatePath, certificatePassword); + + var sslOptions = new EonaCat.Network.SslOptions + { + SslProtocol = SslProtocols.Tls12 | SslProtocols.Tls13, + CheckCertificateRevocation = false, + ClientCertificates = new X509CertificateCollection { loadedCertificate }, + CertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => + { + // Accept all certificates for testing purposes + return true; + }, + }; + + long serverMessageCount = 0; + var tcpServer = new EonaCat.Network.SocketTcpServer(IPAddress.Loopback, 1111, loadedCertificate, sslOptions); + tcpServer.OnConnect += async (remoteInfo) => + { + Console.WriteLine($"Connected {remoteInfo.NickName}"); + await tcpServer.SendToAsync(remoteInfo.Socket, Encoding.UTF8.GetBytes($"ServerMessage: {++serverMessageCount}")); + }; + + tcpServer.OnDisconnect += (remoteInfo) => Console.WriteLine($"Disconnected from {remoteInfo.EndPoint}"); + tcpServer.OnError += (ex, message) => Console.WriteLine($"Error: {message}{Environment.NewLine}{ex}"); + tcpServer.OnReceive += async (remoteInfo, data) => + { + Console.WriteLine($"Received from {remoteInfo}: {data}"); + await tcpServer.SendToAsync(remoteInfo.Socket, Encoding.UTF8.GetBytes($"ServerMessage: {++serverMessageCount}")); + }; + await tcpServer.StartAsync().ConfigureAwait(false); + + Console.WriteLine("TCP Server started."); + Console.WriteLine("Press any key to connect the TCP client..."); + Console.ReadKey(); + + for (int i = 0; i < 100; i++) + { + Console.WriteLine($"Connecting TCP client {i + 1}..."); + + // Create a TCP client + long clientMessageCount = 0; + var tcpClient = new EonaCat.Network.SocketTcpClient(); + tcpClient.OnConnect += async (remoteInfo) => + { + Console.WriteLine($"Connected to {remoteInfo.EndPoint}"); + await tcpClient.SendAsync(Encoding.UTF8.GetBytes($"{++clientMessageCount}")).ConfigureAwait(false); + }; + + tcpClient.OnReceive += async (remoteInfo) => + { + Console.WriteLine($"Received from {remoteInfo}: {remoteInfo.Data}"); + await tcpServer.SendToAsync(remoteInfo.Socket, Encoding.UTF8.GetBytes($"ServerMessage: {++serverMessageCount}")); + }; + tcpClient.OnDisconnect += (remoteInfo) => Console.WriteLine($"Disconnected from {remoteInfo.EndPoint}"); + tcpClient.OnError += (ex, message) => Console.WriteLine($"Error: {message}{Environment.NewLine}{ex}"); + await tcpClient.ConnectAsync("127.0.0.1", 1111, true, sslOptions).ConfigureAwait(false); + + Console.WriteLine($"TCP Client {i} connected to server."); + } + + Console.WriteLine("Press any key to stop the server and client..."); + Console.ReadKey(); + } + private static async Task CreateServerAndClientAsync() { var serverUri = "wss://localhost:8443"; diff --git a/EonaCat.Network.Tester/TestModule.cs b/EonaCat.Network.Tester/TestModule.cs deleted file mode 100644 index 13d372b..0000000 --- a/EonaCat.Network.Tester/TestModule.cs +++ /dev/null @@ -1,16 +0,0 @@ -// This file is part of the EonaCat project(s) which is released under the Apache License. -// See the LICENSE file or go to https://EonaCat.com/License for full license details. - -using EonaCat.WebSockets; - -internal class TestModule : AsyncWebSocketServerModule -{ - public TestModule() - : base("/Welcome") - { - } - public override async Task OnSessionTextReceived(AsyncWebSocketSession session, string text) - { - await session.SendTextAsync(text); - } -} \ No newline at end of file diff --git a/ProxyTester/ProxyTester.Client/ProxyTester.Client.sln b/ProxyTester/ProxyTester.Client/ProxyTester.Client.sln new file mode 100644 index 0000000..ae0f349 --- /dev/null +++ b/ProxyTester/ProxyTester.Client/ProxyTester.Client.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36414.22 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxyTester.Client", "ProxyTester.Client\ProxyTester.Client.csproj", "{ED4C1612-ABFE-491B-AF0C-90F2647C1F51}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxyTester.Server", "..\ProxyTester.Server\ProxyTester.Server\ProxyTester.Server.csproj", "{DE7E42AB-EC8A-472D-B379-6E1DB1E1E96C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ED4C1612-ABFE-491B-AF0C-90F2647C1F51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED4C1612-ABFE-491B-AF0C-90F2647C1F51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED4C1612-ABFE-491B-AF0C-90F2647C1F51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED4C1612-ABFE-491B-AF0C-90F2647C1F51}.Release|Any CPU.Build.0 = Release|Any CPU + {DE7E42AB-EC8A-472D-B379-6E1DB1E1E96C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE7E42AB-EC8A-472D-B379-6E1DB1E1E96C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE7E42AB-EC8A-472D-B379-6E1DB1E1E96C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE7E42AB-EC8A-472D-B379-6E1DB1E1E96C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {27ABD586-54C9-4ECB-B2B0-BF0C21B80D31} + EndGlobalSection +EndGlobal diff --git a/ProxyTester/ProxyTester.Client/ProxyTester.Client/Program.cs b/ProxyTester/ProxyTester.Client/ProxyTester.Client/Program.cs new file mode 100644 index 0000000..46e78c0 --- /dev/null +++ b/ProxyTester/ProxyTester.Client/ProxyTester.Client/Program.cs @@ -0,0 +1,86 @@ +using EonaCat.Connections.Models; +using System.Net.Sockets; + +namespace EonaCat.Connections.Client.Example +{ + // This file is part of the EonaCat project(s) which is released under the Apache License. + // See the LICENSE file or go to https://EonaCat.com/license for full license details. + + public class Program + { + private static NetworkClient _client; + + public static async Task Main(string[] args) + { + for (int i = 0; i < 100; i++) + { + await CreateClientAsync().ConfigureAwait(false); + } + + while (true) + { + if (!_client.IsConnected) + { + await Task.Delay(1000).ConfigureAwait(false); + continue; + } + + Console.Write("Enter message to send (or 'exit' to quit): "); + var message = Console.ReadLine(); + + if (!string.IsNullOrEmpty(message) && message.Equals("exit", StringComparison.OrdinalIgnoreCase)) + { + await _client.DisconnectAsync().ConfigureAwait(false); + break; + } + + if (!string.IsNullOrEmpty(message)) + { + await _client.SendAsync(message).ConfigureAwait(false); + } + } + } + + private static async Task CreateClientAsync() + { + var config = new Configuration + { + Protocol = ProtocolType.TCP, + Host = "127.0.0.1", + Port = 2222, + UseSsl = true, + UseAesEncryption = true, + AesPassword = "EonaCat.Connections.Password", + Certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2("certificate.pfx", "p@ss"), + }; + + _client = new NetworkClient(config); + + _client.OnGeneralError += (sender, e) => + Console.WriteLine($"Error: {e.Message}"); + + // Subscribe to events + _client.OnConnected += async (sender, e) => + { + Console.WriteLine($"Connected to server at {e.RemoteEndPoint}"); + + // Set nickname + await _client.SendNicknameAsync("TestUser"); + + // Send a message + await _client.SendAsync("Hello server!"); + }; + + _client.OnDataReceived += (sender, e) => + Console.WriteLine($"Server says: {(e.IsBinary ? $"{e.Data.Length} bytes" : e.StringData)}"); + + _client.OnDisconnected += (sender, e) => + { + Console.WriteLine("Disconnected from server"); + }; + + Console.WriteLine("Connecting to server..."); + await _client.ConnectAsync(); + } + } +} \ No newline at end of file diff --git a/ProxyTester/ProxyTester.Client/ProxyTester.Client/ProxyTester.Client.csproj b/ProxyTester/ProxyTester.Client/ProxyTester.Client/ProxyTester.Client.csproj new file mode 100644 index 0000000..ebb45b4 --- /dev/null +++ b/ProxyTester/ProxyTester.Client/ProxyTester.Client/ProxyTester.Client.csproj @@ -0,0 +1,20 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + PreserveNewest + + + + diff --git a/ProxyTester/ProxyTester.Server/ProxyTester.Server/Program.cs b/ProxyTester/ProxyTester.Server/ProxyTester.Server/Program.cs new file mode 100644 index 0000000..5c53864 --- /dev/null +++ b/ProxyTester/ProxyTester.Server/ProxyTester.Server/Program.cs @@ -0,0 +1,95 @@ +using EonaCat.Connections.Models; +using System.Net.Sockets; + +namespace EonaCat.Connections.Server.Example +{ + // This file is part of the EonaCat project(s) which is released under the Apache License. + // See the LICENSE file or go to https://EonaCat.com/license for full license details. + + public class Program + { + private static NetworkServer _server; + + public static void Main(string[] args) + { + CreateServerAsync().ConfigureAwait(false); + + while (true) + { + Console.Write("Enter message to send (or 'exit' to quit): "); + var message = Console.ReadLine(); + if (!string.IsNullOrEmpty(message) && message.Equals("exit", StringComparison.OrdinalIgnoreCase)) + { + _server.Stop(); + _server.Dispose(); + Console.WriteLine("Server stopped."); + break; + } + + if (!string.IsNullOrEmpty(message)) + { + _server.BroadcastAsync(message).ConfigureAwait(false); + } + } + } + + private static async Task CreateServerAsync() + { + var config = new Configuration + { + Protocol = ProtocolType.TCP, + Port = 1111, + UseSsl = true, + UseAesEncryption = true, + MaxConnections = 100000, + AesPassword = "EonaCat.Connections.Password", + Certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2("certificate.pfx", "p@ss") + }; + + _server = new NetworkServer(config); + + // Subscribe to events + _server.OnConnected += (sender, e) => + Console.WriteLine($"Client {e.ClientId} connected from {e.RemoteEndPoint}"); + + _server.OnConnectedWithNickname += (sender, e) => + Console.WriteLine($"Client {e.ClientId} connected with nickname: {e.Nickname}"); + + _server.OnDataReceived += async (sender, e) => + { + if (e.HasNickname) + { + Console.WriteLine($"Received from {e.Nickname}: {(e.IsBinary ? $"{e.Data.Length} bytes" : e.StringData)}"); + } + else + { + Console.WriteLine($"Received from {e.ClientId}: {(e.IsBinary ? $"{e.Data.Length} bytes" : e.StringData)}"); + } + + // Echo back the message + if (e.IsBinary) + { + await _server.SendToClientAsync(e.ClientId, e.Data); + } + else + { + await _server.SendToClientAsync(e.ClientId, $"Echo: {e.StringData}"); + } + }; + + _server.OnDisconnected += (sender, e) => + { + if (e.HasNickname) + { + Console.WriteLine($"Client {e.Nickname} disconnected"); + } + else + { + Console.WriteLine($"Client {e.ClientId} disconnected"); + } + }; + + await _server.StartAsync(); + } + } +} \ No newline at end of file diff --git a/ProxyTester/ProxyTester.Server/ProxyTester.Server/ProxyTester.Server.csproj b/ProxyTester/ProxyTester.Server/ProxyTester.Server/ProxyTester.Server.csproj new file mode 100644 index 0000000..ebb45b4 --- /dev/null +++ b/ProxyTester/ProxyTester.Server/ProxyTester.Server/ProxyTester.Server.csproj @@ -0,0 +1,20 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + PreserveNewest + + + +