diff --git a/f-cln/Properties/launchSettings.json b/f-cln/Properties/launchSettings.json index 0826aa4..d7b849a 100644 --- a/f-cln/Properties/launchSettings.json +++ b/f-cln/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "f-cln": { "commandName": "Project", - "commandLineArgs": "--port 3113 -i 172.22.176.1" + "commandLineArgs": "-p 1771" } } } \ No newline at end of file diff --git a/f-cln/f-cln.csproj b/f-cln/f-cln.csproj index 0b803e7..e29aacb 100644 --- a/f-cln/f-cln.csproj +++ b/f-cln/f-cln.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 f_cln enable enable diff --git a/f-srv/Program.cs b/f-srv/Program.cs index 71f5612..7e1691f 100644 --- a/f-srv/Program.cs +++ b/f-srv/Program.cs @@ -20,7 +20,7 @@ namespace f_srv Option ipOption = new("address", new[] { "--ip", "-i" }) { Description = "IP адрес для прослушивания (по умолчанию: все интерфейсы)", - DefaultValueFactory = parseResult => IPAddress.Any, + DefaultValueFactory = parseResult => IPAddress.Any, CustomParser = result => { if (result.Tokens.Count != 1) @@ -80,41 +80,59 @@ namespace f_srv // Запускаем сервер в отдельной задаче var serverTask = Task.Run(() => StartServer(ip, port, _cancellationTokenSource.Token)); - - // Ожидаем нажатие клавиши с явной обработкой - Console.WriteLine("Сервер запущен. Нажмите любую клавишу для остановки..."); - - // Ждем нажатия клавиши в отдельном потоке - var keyTask = Task.Run(() => + + Console.WriteLine("Сервер запущен. Введите 'Exit' для остановки..."); + + // Ждем ввод строки "Exit" в отдельном потоке + var exitTask = Task.Run(() => { - Console.ReadKey(true); // true - не отображать нажатую клавишу - return true; + while (!_cancellationTokenSource.IsCancellationRequested) + { + var input = Console.ReadLine(); + if (!string.IsNullOrEmpty(input) && + input.Trim().Equals("Exit", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + return false; }); - - // Ожидаем либо нажатия клавиши, либо завершения сервера - await Task.WhenAny(serverTask, keyTask); - - if (!_cancellationTokenSource.IsCancellationRequested) + + // Ожидаем либо ввод "Exit", либо завершение сервера + var completedTask = await Task.WhenAny(serverTask, exitTask); + + if (completedTask == exitTask && exitTask.Result) { - // Отправляем сигнал отмены - _cancellationTokenSource.Cancel(); - - // Останавливаем listener - _listener?.Stop(); - - // Даем серверу время на корректное завершение - try + // Пользователь ввел Exit + if (!_cancellationTokenSource.IsCancellationRequested) { - await Task.WhenAny(serverTask, Task.Delay(2000)); + Console.WriteLine("Остановка сервера..."); + _cancellationTokenSource.Cancel(); + _listener?.Stop(); + + // Даем серверу время на корректное завершение + try + { + await Task.WhenAny(serverTask, Task.Delay(2000)); + } + catch + { + // Игнорируем исключения при завершении + } + + Console.WriteLine("Сервер остановлен."); } - catch - { - // Игнорируем исключения при завершении - } - - Console.WriteLine("Сервер остановлен."); } - + else + { + // Сервер завершился сам (ошибка или другая причина) + if (!_cancellationTokenSource.IsCancellationRequested) + { + _cancellationTokenSource.Cancel(); + } + Console.WriteLine("Сервер завершил работу."); + } + return 0; } else @@ -146,11 +164,11 @@ namespace f_srv // Ожидание подключения клиента с таймаутом для проверки отмены var acceptTask = _listener.AcceptTcpClientAsync(); var completedTask = await Task.WhenAny(acceptTask, Task.Delay(1000, cancellationToken)); - + if (completedTask == acceptTask && !cancellationToken.IsCancellationRequested) { var client = await acceptTask; - + // Обработка клиента в отдельной задаче _ = Task.Run(async () => await HandleClient(client, cancellationToken)); } @@ -212,7 +230,7 @@ namespace f_srv { // Чтение строки (до символа новой строки) var line = await reader.ReadLineAsync(); - + if (line == null) { // Клиент отключился