void acceptLoop() { try { try { while (true) { TcpClient client = listener.AcceptTcpClient(); tcpConfig.ApplyTo(client); // TODO keep track of connections before they are in connections dictionary // this might not be a problem as HandshakeAndReceiveLoop checks for stop // and returns/disposes before sending message to queue Connection conn = new Connection(client, AfterConnectionDisposed); Log.Info($"A client connected {conn}"); // handshake needs its own thread as it needs to wait for message from client Thread receiveThread = new Thread(() => HandshakeAndReceiveLoop(conn)); conn.receiveThread = receiveThread; receiveThread.IsBackground = true; receiveThread.Start(); } } catch (SocketException) { // check for Interrupted/Abort Utils.CheckForInterupt(); throw; } } catch (ThreadInterruptedException e) { Log.InfoException(e); } catch (ThreadAbortException e) { Log.InfoException(e); } catch (Exception e) { Log.Exception(e); } }
public override void Connect(Uri serverAddress) { state = ClientState.Connecting; // create connection here before thread so that send queue exist before connected TcpClient client = new TcpClient(); tcpConfig.ApplyTo(client); // create connection object here so dispose correctly disconnects on failed connect conn = new Connection(client, AfterConnectionDisposed); Thread receiveThread = new Thread(() => ConnectAndReceiveLoop(serverAddress)); receiveThread.IsBackground = true; receiveThread.Start(); }
void ConnectAndReceiveLoop(Uri serverAddress) { try { TcpClient client = new TcpClient(); tcpConfig.ApplyTo(client); // create connection object here so dispose correctly disconnects on failed connect conn = new Connection(client, AfterConnectionDisposed); conn.receiveThread = Thread.CurrentThread; try { client.Connect(serverAddress.Host, serverAddress.Port); } catch (SocketException) { client.Dispose(); throw; } bool success = sslHelper.TryCreateStream(conn, serverAddress); if (!success) { Log.Warn("Failed to create Stream"); conn.Dispose(); return; } success = handshake.TryHandshake(conn, serverAddress); if (!success) { Log.Warn("Failed Handshake"); conn.Dispose(); return; } Log.Info("HandShake Successful"); state = ClientState.Connected; receiveQueue.Enqueue(new Message(EventType.Connected)); Thread sendThread = new Thread(() => { SendLoop.Config sendConfig = new SendLoop.Config( conn, bufferSize: Constants.HeaderSize + Constants.MaskSize + maxMessageSize, setMask: true); SendLoop.Loop(sendConfig); }); conn.sendThread = sendThread; sendThread.IsBackground = true; sendThread.Start(); ReceiveLoop.Config config = new ReceiveLoop.Config(conn, maxMessageSize, false, receiveQueue, bufferPool); ReceiveLoop.Loop(config); } catch (ThreadInterruptedException e) { Log.InfoException(e); } catch (ThreadAbortException e) { Log.InfoException(e); } catch (Exception e) { Log.Exception(e); } finally { // close here in case connect fails conn?.Dispose(); } }