public void StartServerAfterClientShouldWork() { using var server = TcpConnectionFactory.CreateServer( 15003); using var client = TcpConnectionFactory.CreateClient( IPAddress.Loopback, 15003); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); AssertEx.IsTrue(() => server.State == ConnectionState.Connected); AssertEx.IsTrue(() => client.State == ConnectionState.Connected); server.Stop(); client.Stop(); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); }
public async Task MessageReceivedWithStreamAndUsingBufferStreamShouldWork() { var serverReceivedDataEvent = new AsyncAutoResetEvent(false); int currentMessageSize = -1; using var server = TcpConnectionFactory.CreateServer(15022, new ServerConnectionSettings(useBufferedStream: true)); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15022, new ClientConnectionSettings(useBufferedStream: true)); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Start(receivedActionStreamAsync: async(connection, stream, cancellationToken) => { var bytesRead = await stream.ReadAsync(new byte[stream.Length], 0, (int)stream.Length, cancellationToken); Assert.AreEqual(currentMessageSize, bytesRead); serverReceivedDataEvent.Set(); }, connectionStateChangedAction: (connection, fromState, toState) => { }); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new byte[currentMessageSize = 10]); (await serverReceivedDataEvent.WaitAsync(10000)).ShouldBeTrue(); await client.SendDataAsync(new byte[currentMessageSize = 120]); (await serverReceivedDataEvent.WaitAsync(10000)).ShouldBeTrue(); }
public async Task MessageLargerThan64KBShouldBeTransimittedWithoutProblems() { var serverReceivedDataEvent = new AsyncAutoResetEvent(false); const int messageSize = 1024 * 128; //128kb using var server = TcpConnectionFactory.CreateServer(15010); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15010); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); server.Start((connection, data) => { Assert.AreEqual(messageSize, data.Length); serverReceivedDataEvent.Set(); }, connectionStateChangedAction: (connection, fromState, toState) => { }); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new byte[messageSize]); (await serverReceivedDataEvent.WaitAsync(10000)).ShouldBeTrue(); }
public void ServerShouldMoveStateToLinkErrorIfClientDoesntConnect() { using var connectionLinkErrorEvent = new AutoResetEvent(false); using var connectionOkEvent = new AutoResetEvent(false); using var server = TcpConnectionFactory.CreateServer(15006, new ServerConnectionSettings(connectionTimeoutMilliseconds: 1000)); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.LinkError) { connectionLinkErrorEvent.Set(); } else if (toState == ConnectionState.Connected) { connectionOkEvent.Set(); } }); connectionLinkErrorEvent.WaitOne(10000).ShouldBeTrue(); var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15006); client.Start(); connectionOkEvent.WaitOne(10000).ShouldBeTrue(); }
public void ClientShouldMoveStateToLinkErrorIfServerDoesntExist() { using var connectionLinkErrorEvent = new AutoResetEvent(false); using var connectionOkEvent = new AutoResetEvent(false); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15005); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.LinkError) { connectionLinkErrorEvent.Set(); } else if (toState == ConnectionState.Connected) { connectionOkEvent.Set(); } }); connectionLinkErrorEvent.WaitOne(10000).ShouldBeTrue(); var server = TcpConnectionFactory.CreateServer(15005); server.Start(); connectionOkEvent.WaitOne(10000).ShouldBeTrue(); }
public void ClientShouldMoveStateToLinkErrorIfServerDoesntExist() { using var connectionLinkErrorEvent = new AutoResetEvent(false); using var connectionOkEvent = new AutoResetEvent(false); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15005); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { if (toState == ConnectionState.LinkError) { connectionLinkErrorEvent.Set(); } else if (toState == ConnectionState.Connected) { connectionOkEvent.Set(); } }, receivedActionStreamAsync: (connection, stream, cancellationToken) => { System.Diagnostics.Debug.Assert(false); return(Task.CompletedTask); }); connectionLinkErrorEvent.WaitOne(10000).ShouldBeTrue(); var server = TcpConnectionFactory.CreateServer(15005); server.Start(); connectionOkEvent.WaitOne(10000).ShouldBeTrue(); }
private static void RunClient() { using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15000); client.Start( receivedAction: (connection, data) => Console.WriteLine($"Message from server: {Encoding.UTF8.GetString(data)}"), connectionStateChangedAction: (connection, fromState, toState) => Console.WriteLine($"Client connection state changed from {fromState} to {toState}")); RunConnection(client); }
/// <summary> /// relays the input clientStream to the server at the specified host name & port with the given httpCmd & headers as prefix /// Usefull for websocket requests /// </summary> /// <param name="bufferSize"></param> /// <param name="connectionTimeOutSeconds"></param> /// <param name="remoteHostName"></param> /// <param name="httpCmd"></param> /// <param name="httpVersion"></param> /// <param name="requestHeaders"></param> /// <param name="isHttps"></param> /// <param name="remotePort"></param> /// <param name="supportedProtocols"></param> /// <param name="remoteCertificateValidationCallback"></param> /// <param name="localCertificateSelectionCallback"></param> /// <param name="clientStream"></param> /// <param name="tcpConnectionFactory"></param> /// <returns></returns> internal static async Task SendRaw(int bufferSize, int connectionTimeOutSeconds, string remoteHostName, int remotePort, string httpCmd, Version httpVersion, Dictionary <string, HttpHeader> requestHeaders, bool isHttps, SslProtocols supportedProtocols, RemoteCertificateValidationCallback remoteCertificateValidationCallback, LocalCertificateSelectionCallback localCertificateSelectionCallback, Stream clientStream, TcpConnectionFactory tcpConnectionFactory, IPEndPoint upStreamEndPoint) { //prepare the prefix content StringBuilder sb = null; if (httpCmd != null || requestHeaders != null) { sb = new StringBuilder(); if (httpCmd != null) { sb.Append(httpCmd); sb.Append(ProxyConstants.NewLine); } if (requestHeaders != null) { foreach (var header in requestHeaders.Select(t => t.Value.ToString())) { sb.Append(header); sb.Append(ProxyConstants.NewLine); } } sb.Append(ProxyConstants.NewLine); } var tcpConnection = await tcpConnectionFactory.CreateClient(bufferSize, connectionTimeOutSeconds, remoteHostName, remotePort, httpVersion, isHttps, supportedProtocols, remoteCertificateValidationCallback, localCertificateSelectionCallback, null, null, clientStream, upStreamEndPoint); try { Stream tunnelStream = tcpConnection.Stream; //Now async relay all server=>client & client=>server data var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream); var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream); await Task.WhenAll(sendRelay, receiveRelay); } finally { tcpConnection.Dispose(); } }
public void CancelClientPendingConnectionShouldJustWork() { using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15002); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { }); client.Stop(); AssertEx.IsTrue(() => client.State == ConnectionState.Disconnected); }
public async Task ConnectionListenerShouldAcceptNewConnection() { using var multiPeerServer = TcpConnectionFactory.CreateMultiPeerServer(14000); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 14000); var receivedBackFromServerEvent = new AsyncAutoResetEvent(false); IConnection newConnection = null; multiPeerServer.Start((listener, c) => { newConnection = c; newConnection.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent(4); var buffer = memoryOwner.Memory.Slice(0, 4); await stream.ReadAsync(buffer, cancellationToken); var pingString = Encoding.UTF8.GetString(buffer.Span); await connection.SendDataAsync( new Memory <byte>(Encoding.UTF8.GetBytes($"SERVER RECEIVED: {pingString}"))); }, connectionStateChangedAction: (c, fromState, toState) => { } ); }); client.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent(21); var buffer = memoryOwner.Memory.Slice(0, 21); await stream.ReadAsync(buffer, cancellationToken); if (Encoding.UTF8.GetString(buffer.Span) == "SERVER RECEIVED: PING") { receivedBackFromServerEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); await client.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new Memory <byte>(Encoding.UTF8.GetBytes("PING"))); (await receivedBackFromServerEvent.WaitAsync(100000)).ShouldBeTrue(); multiPeerServer.Stop(); }
public async Task SendMessagesUsingMemoryBuffer() { using var server = TcpConnectionFactory.CreateServer(11001); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 11001); var receivedFromClientEvent = new AsyncAutoResetEvent(false); var receivedFromServerEvent = new AsyncAutoResetEvent(false); client.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent((int)stream.Length); await stream.ReadAsync(memoryOwner.Memory, cancellationToken); if (Encoding.UTF8.GetString(memoryOwner.Memory.Span) == "SENT FROM SERVER") { receivedFromServerEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); server.Start( receivedActionStreamAsync: async(connection, stream, cancellationToken) => { using var memoryOwner = MemoryPool <byte> .Shared.Rent((int)stream.Length); await stream.ReadAsync(memoryOwner.Memory, cancellationToken); if (Encoding.UTF8.GetString(memoryOwner.Memory.Span) == "SENT FROM CLIENT") { receivedFromClientEvent.Set(); } }, connectionStateChangedAction: (c, fromState, toState) => { } ); //WaitHandle.WaitAll(new[] { clientConnectedEvent, serverConnectedEvent }, 4000).ShouldBeTrue(); await client.WaitForStateAsync(ConnectionState.Connected); await server.WaitForStateAsync(ConnectionState.Connected); await client.SendDataAsync(new Memory <byte>(Encoding.UTF8.GetBytes("SENT FROM CLIENT"))); await server.SendDataAsync(new Memory <byte>(Encoding.UTF8.GetBytes("SENT FROM SERVER"))); //WaitHandle.WaitAll(new[] { receivedFromClientEvent, receivedFromServerEvent }, 10000).ShouldBeTrue(); (await receivedFromClientEvent.WaitAsync(10000)).ShouldBe(true); (await receivedFromServerEvent.WaitAsync(10000)).ShouldBe(true); }
private static void RunClient() { using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15000); client.Start( receivedAction: (connection, data) => Console.WriteLine($"Message from server: {Encoding.UTF8.GetString(data)}"), connectionStateChangedAction: (connection, fromState, toState) => Console.WriteLine($"Client connection state changed from {fromState} to {toState}")); while (true) { var message = Console.ReadLine(); if (message == null) { break; } client.SendDataAsync(Encoding.UTF8.GetBytes(message)).Wait(); } }
public void TcpConnectionShouldBeFullDuplex() { using var server = TcpConnectionFactory.CreateMultiPeerServer(15025); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15025); server.Start((listener, connection) => { connection.Start(async(connection, stream, cancellationToken) => { var buffer = new byte[10]; stream.Read(buffer, 0, 10); await connection.SendAsync((outStream, outCancellationToken) => { outStream.Write(buffer, 0, 10); return(Task.CompletedTask); }); }); }); int receivedMessageBackCount = 0; client.Start((connection, stream, cancellationToken) => { stream.Read(new byte[10], 0, 10); receivedMessageBackCount++; return(Task.CompletedTask); }); client.WaitForState(ConnectionState.Connected); for (int i = 0; i < 1000; i++) { client.SendAsync((stream, cancellationToken) => { stream.Write(new byte[10], 0, 10); return(Task.CompletedTask); }); } AssertEx.IsTrue(() => receivedMessageBackCount == 1000); }
public void ClientShouldReconnectToServerAfterServerRestart() { _logger.Verbose("Begin test ClientShouldReconnectToServerAfterServerRestart"); using var server = TcpConnectionFactory.CreateServer(15004); using var client = TcpConnectionFactory.CreateClient(IPAddress.Loopback, 15004); server.Start(connectionStateChangedAction: (connection, fromState, toState) => { _logger.Verbose($"Server state change from {fromState} to {toState}"); }); client.Start(connectionStateChangedAction: (connection, fromState, toState) => { _logger.Verbose($"Client state change from {fromState} to {toState}"); }); AssertEx.IsTrue(() => server.State == ConnectionState.Connected); AssertEx.IsTrue(() => client.State == ConnectionState.Connected); _logger.Verbose($"Stop server"); server.Stop(); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); AssertEx.IsTrue(() => client.State == ConnectionState.LinkError); _logger.Verbose($"Start server"); server.Start(); _logger.Verbose($"Stop server"); server.Stop(); _logger.Verbose($"Stop client"); client.Stop(); AssertEx.IsTrue(() => server.State == ConnectionState.Disconnected); AssertEx.IsTrue(() => client.State == ConnectionState.Disconnected); _logger.Verbose("End test ClientShouldReconnectToServerAfterServerRestart"); }
/// <summary> /// relays the input clientStream to the server at the specified host name and port with the given httpCmd and headers as prefix /// Usefull for websocket requests /// </summary> /// <param name="server"></param> /// <param name="remoteHostName"></param> /// <param name="remotePort"></param> /// <param name="httpCmd"></param> /// <param name="httpVersion"></param> /// <param name="requestHeaders"></param> /// <param name="isHttps"></param> /// <param name="clientStream"></param> /// <param name="tcpConnectionFactory"></param> /// <param name="connection"></param> /// <returns></returns> internal static async Task SendRaw(ProxyServer server, string remoteHostName, int remotePort, string httpCmd, Version httpVersion, Dictionary <string, HttpHeader> requestHeaders, bool isHttps, Stream clientStream, TcpConnectionFactory tcpConnectionFactory, TcpConnection connection = null) { //prepare the prefix content StringBuilder sb = null; if (httpCmd != null || requestHeaders != null) { sb = new StringBuilder(); if (httpCmd != null) { sb.Append(httpCmd); sb.Append(ProxyConstants.NewLine); } if (requestHeaders != null) { foreach (var header in requestHeaders.Select(t => t.Value.ToString())) { sb.Append(header); sb.Append(ProxyConstants.NewLine); } } sb.Append(ProxyConstants.NewLine); } bool connectionCreated = false; TcpConnection tcpConnection; //create new connection if connection is null if (connection == null) { tcpConnection = await tcpConnectionFactory.CreateClient(server, remoteHostName, remotePort, httpVersion, isHttps, null, null); connectionCreated = true; } else { tcpConnection = connection; } try { Stream tunnelStream = tcpConnection.Stream; //Now async relay all server=>client & client=>server data var sendRelay = clientStream.CopyToAsync(sb?.ToString() ?? string.Empty, tunnelStream); var receiveRelay = tunnelStream.CopyToAsync(string.Empty, clientStream); await Task.WhenAll(sendRelay, receiveRelay); } finally { //if connection was null //then a new connection was created //so dispose the new connection if (connectionCreated) { tcpConnection.Dispose(); Interlocked.Decrement(ref server.serverConnectionCount); } } }