using System; using System.CommandLine; using System.CommandLine.Parsing; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Collections.Generic; using System.Linq; namespace f_srv { class Program { private static CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private static TcpListener? _listener; private static bool _isPaused = false; private static readonly object _lockObject = new object(); private static List _connectedClients = new List(); private static bool _isRunning = false; static async Task Main(string[] args) { // Создание команды с аргументами Option ipOption = new("address", new[] { "--ip", "-i" }) { Description = "IP адрес для прослушивания (по умолчанию: все интерфейсы)", DefaultValueFactory = parseResult => IPAddress.Any }; Option portOption = new("port", new[] { "--port", "-p" }) { Description = "Порт для прослушивания (по умолчанию: 1771)", DefaultValueFactory = parseResult => 1771 }; var rootCommand = new RootCommand("Сервер для получения строк и отправки их в обратном порядке") { ipOption, portOption }; ParseResult parseResult = rootCommand.Parse(args); if (parseResult.Errors.Count == 0) { IPAddress? ip = parseResult.GetValue(ipOption); int port = parseResult.GetValue(portOption); if (ip == null) { Console.Error.WriteLine("Ошибка: IP адрес не указан или имеет неверный формат"); return 2; } // Запускаем сервер Console.WriteLine($"Запуск сервера на {ip}:{port}"); Console.WriteLine("Команды управления сервером:"); Console.WriteLine(" старт - запустить сервер"); Console.WriteLine(" стоп - остановить сервер"); Console.WriteLine(" пауза - приостановить обработку подключений"); Console.WriteLine(" продолжить - возобновить обработку подключений"); Console.WriteLine(" рестарт - перезапустить сервер"); Console.WriteLine(" статус - показать текущее состояние сервера"); Console.WriteLine(" выход - завершить программу"); Console.WriteLine(); // Команда старт по умолчанию await StartServer(ip, port); _isRunning = true; // Основной цикл обработки команд while (true) { Console.Write("сервер> "); var command = Console.ReadLine()?.Trim().ToLower(); if (string.IsNullOrEmpty(command)) continue; switch (command) { case "старт": if (!_isRunning) { await StartServer(ip, port); _isRunning = true; Console.WriteLine("Сервер запущен"); } else { Console.WriteLine("Сервер уже запущен"); } break; case "стоп": if (_isRunning) { await StopServer(); _isRunning = false; Console.WriteLine("Сервер остановлен"); } else { Console.WriteLine("Сервер уже остановлен"); } break; case "пауза": if (_isRunning && !_isPaused) { _isPaused = true; Console.WriteLine("Сервер приостановлен. Новые подключения не обрабатываются."); } else if (!_isRunning) { Console.WriteLine("Сервер не запущен"); } else { Console.WriteLine("Сервер уже приостановлен"); } break; case "продолжить": if (_isRunning && _isPaused) { _isPaused = false; Console.WriteLine("Сервер возобновил работу"); } else if (!_isRunning) { Console.WriteLine("Сервер не запущен"); } else { Console.WriteLine("Сервер уже работает"); } break; case "рестарт": if (_isRunning) { await StopServer(); Console.WriteLine("Сервер остановлен"); } await Task.Delay(1000); // Небольшая задержка перед перезапуском await StartServer(ip, port); _isRunning = true; _isPaused = false; Console.WriteLine("Сервер перезапущен"); break; case "статус": PrintServerStatus(); break; case "выход": case "exit": Console.WriteLine("Завершение работы сервера..."); if (_isRunning) { await StopServer(); } _cancellationTokenSource.Cancel(); return 0; case "помощь": case "help": PrintHelp(); break; default: Console.WriteLine($"Неизвестная команда: {command}"); Console.WriteLine("Введите 'помощь' для списка команд"); break; } } } else { foreach (ParseError parseError in parseResult.Errors) { Console.Error.WriteLine(parseError.Message); } return 1; } } static async Task StartServer(IPAddress ip, int port) { try { lock (_lockObject) { _isPaused = false; _connectedClients.Clear(); } // Создание TCP listener _listener = new TcpListener(ip, port); _listener.Start(); Console.WriteLine($"Сервер запущен на {ip}:{port}"); Console.WriteLine("Ожидание подключений..."); // Запускаем обработку подключений в фоновом потоке _ = Task.Run(() => AcceptConnectionsAsync()); } catch (Exception ex) { Console.WriteLine($"Ошибка при запуске сервера: {ex.Message}"); throw; } } static async Task AcceptConnectionsAsync() { while (!_cancellationTokenSource.Token.IsCancellationRequested) { try { // Если сервер на паузе, ждем if (_isPaused) { await Task.Delay(1000); continue; } // Ожидание подключения клиента var client = await _listener!.AcceptTcpClientAsync(); lock (_lockObject) { _connectedClients.Add(client); } // Обработка клиента в отдельной задаче _ = Task.Run(async () => await HandleClient(client)); } catch (ObjectDisposedException) { // Listener был остановлен break; } catch (Exception ex) { if (!_cancellationTokenSource.Token.IsCancellationRequested) { Console.WriteLine($"Ошибка при принятии подключения: {ex.Message}"); } } } } static async Task HandleClient(TcpClient client) { var clientEndPoint = client.Client.RemoteEndPoint; Console.WriteLine($"Подключен клиент: {clientEndPoint}"); try { using (client) using (var stream = client.GetStream()) using (var reader = new StreamReader(stream, Encoding.UTF8)) using (var writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true }) { // Отправка приветственного сообщения await writer.WriteLineAsync($"hello {clientEndPoint}"); while (client.Connected && !_cancellationTokenSource.Token.IsCancellationRequested) { try { // Чтение строки (до символа новой строки) var line = await reader.ReadLineAsync(); if (line == null) { // Клиент отключился Console.WriteLine($"Клиент отключился: {clientEndPoint}"); break; } // Если сервер на паузе, ждем if (_isPaused) { await writer.WriteLineAsync("Сервер приостановлен. Попробуйте позже."); continue; } Console.WriteLine($"Получено от {clientEndPoint}: {line}"); // Реверсирование строки var reversedString = ReverseString(line); Console.WriteLine($"Отправка: {reversedString}"); // Отправка реверсированной строки обратно клиенту await writer.WriteLineAsync(reversedString); } catch (IOException ex) { // Ошибка ввода/вывода - клиент отключился Console.WriteLine($"Клиент отключился: {clientEndPoint} - {ex.Message}"); break; } } } } catch (Exception ex) { Console.WriteLine($"Ошибка при работе с клиентом {clientEndPoint}: {ex.Message}"); } finally { lock (_lockObject) { _connectedClients.Remove(client); } Console.WriteLine($"Клиент отключен: {clientEndPoint}"); } } static async Task StopServer() { try { // Останавливаем listener _listener?.Stop(); // Закрываем все подключенные клиенты lock (_lockObject) { foreach (var client in _connectedClients.ToList()) { try { client.Close(); } catch { // Игнорируем ошибки при закрытии клиентов } } _connectedClients.Clear(); } _isPaused = false; Console.WriteLine("Сервер остановлен"); } catch (Exception ex) { Console.WriteLine($"Ошибка при остановке сервера: {ex.Message}"); } } static void PrintServerStatus() { Console.WriteLine("\n=== Статус сервера ==="); Console.WriteLine($"Состояние: {(_isRunning ? "Запущен" : "Остановлен")}"); if (_isRunning) { Console.WriteLine($"Режим: {(_isPaused ? "Приостановлен" : "Работает")}"); lock (_lockObject) { Console.WriteLine($"Подключенных клиентов: {_connectedClients.Count}"); foreach (var client in _connectedClients) { try { if (client.Client.RemoteEndPoint is IPEndPoint endPoint) { Console.WriteLine($" {endPoint.Address}:{endPoint.Port}"); } } catch { // Игнорируем клиентов с ошибками } } } } Console.WriteLine("====================\n"); } static void PrintHelp() { Console.WriteLine("\n=== Команды управления сервером ==="); Console.WriteLine(" старт - запустить сервер"); Console.WriteLine(" стоп - остановить сервер"); Console.WriteLine(" пауза - приостановить обработку подключений"); Console.WriteLine(" продолжить - возобновить обработку подключений"); Console.WriteLine(" рестарт - перезапустить сервер"); Console.WriteLine(" статус - показать текущее состояние сервера"); Console.WriteLine(" помощь - показать эту справку"); Console.WriteLine(" выход - завершить программу"); Console.WriteLine("===================================\n"); } static string ReverseString(string s) { var charArray = s.ToCharArray(); Array.Reverse(charArray); return new string(charArray); } } }