static void Main() { LogConsole = LogConsole.Create(LogConsoleFlags.None); LogConsole.ExceptionMode = LogExceptionMode.Full; ParseArgs(); Header(); if (LocalEndPoints.Count > 0) { if (!Quiet) { Log.LogInfo(string.Format("Listening at <cyan>{0}", LocalEndPoints.Keys.Join("<default>, <cyan>"))); } bool useConsole = true; try { while (SystemConsole.KeyAvailable) { SystemConsole.ReadKey(); } } catch { useConsole = false; } DateTime lastEscapePress = DateTime.MinValue; List <Task> listenTasks = new List <Task>(); foreach (TcpListener listener in LocalEndPoints.Values) { Task task = Task.Factory.StartNew(() => { while (!Exit) { TcpClient l_Client = listener.AcceptTcpClient(); LogLevel l_Level = ShowConnects ? LogLevel.Information : LogLevel.Verbose; Log.Write(l_Level, string.Format("Connect from <cyan>{0}", l_Client.Client.RemoteEndPoint)); Task.Factory.StartNew(() => Forward(l_Client)); } }, TaskCreationOptions.LongRunning); listenTasks.Add(task); } if (useConsole) { while (!Exit) { if (SystemConsole.KeyAvailable) { switch (SystemConsole.ReadKey().Key) { case ConsoleKey.Escape: if (lastEscapePress.AddSeconds(1) <= DateTime.Now) { Exit = true; break; } lastEscapePress = DateTime.Now; Log.LogInfo("Press escape again within 1s to exit."); break; } } Thread.Sleep(100); } } else { while (!Exit) { Thread.Sleep(1000); } } } Logger.Flush(); LogConsole.Close(); }