change exit mode
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"f-cln": {
|
"f-cln": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "--port 3113 -i 172.22.176.1"
|
"commandLineArgs": "-p 1771"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<RootNamespace>f_cln</RootNamespace>
|
<RootNamespace>f_cln</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace f_srv
|
|||||||
Option<IPAddress> ipOption = new("address", new[] { "--ip", "-i" })
|
Option<IPAddress> ipOption = new("address", new[] { "--ip", "-i" })
|
||||||
{
|
{
|
||||||
Description = "IP адрес для прослушивания (по умолчанию: все интерфейсы)",
|
Description = "IP адрес для прослушивания (по умолчанию: все интерфейсы)",
|
||||||
DefaultValueFactory = parseResult => IPAddress.Any,
|
DefaultValueFactory = parseResult => IPAddress.Any,
|
||||||
CustomParser = result =>
|
CustomParser = result =>
|
||||||
{
|
{
|
||||||
if (result.Tokens.Count != 1)
|
if (result.Tokens.Count != 1)
|
||||||
@@ -80,41 +80,59 @@ namespace f_srv
|
|||||||
|
|
||||||
// Запускаем сервер в отдельной задаче
|
// Запускаем сервер в отдельной задаче
|
||||||
var serverTask = Task.Run(() => StartServer(ip, port, _cancellationTokenSource.Token));
|
var serverTask = Task.Run(() => StartServer(ip, port, _cancellationTokenSource.Token));
|
||||||
|
|
||||||
// Ожидаем нажатие клавиши с явной обработкой
|
Console.WriteLine("Сервер запущен. Введите 'Exit' для остановки...");
|
||||||
Console.WriteLine("Сервер запущен. Нажмите любую клавишу для остановки...");
|
|
||||||
|
// Ждем ввод строки "Exit" в отдельном потоке
|
||||||
// Ждем нажатия клавиши в отдельном потоке
|
var exitTask = Task.Run(() =>
|
||||||
var keyTask = Task.Run(() =>
|
|
||||||
{
|
{
|
||||||
Console.ReadKey(true); // true - не отображать нажатую клавишу
|
while (!_cancellationTokenSource.IsCancellationRequested)
|
||||||
return true;
|
{
|
||||||
|
var input = Console.ReadLine();
|
||||||
|
if (!string.IsNullOrEmpty(input) &&
|
||||||
|
input.Trim().Equals("Exit", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ожидаем либо нажатия клавиши, либо завершения сервера
|
// Ожидаем либо ввод "Exit", либо завершение сервера
|
||||||
await Task.WhenAny(serverTask, keyTask);
|
var completedTask = await Task.WhenAny(serverTask, exitTask);
|
||||||
|
|
||||||
if (!_cancellationTokenSource.IsCancellationRequested)
|
if (completedTask == exitTask && exitTask.Result)
|
||||||
{
|
{
|
||||||
// Отправляем сигнал отмены
|
// Пользователь ввел Exit
|
||||||
_cancellationTokenSource.Cancel();
|
if (!_cancellationTokenSource.IsCancellationRequested)
|
||||||
|
|
||||||
// Останавливаем listener
|
|
||||||
_listener?.Stop();
|
|
||||||
|
|
||||||
// Даем серверу время на корректное завершение
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -146,11 +164,11 @@ namespace f_srv
|
|||||||
// Ожидание подключения клиента с таймаутом для проверки отмены
|
// Ожидание подключения клиента с таймаутом для проверки отмены
|
||||||
var acceptTask = _listener.AcceptTcpClientAsync();
|
var acceptTask = _listener.AcceptTcpClientAsync();
|
||||||
var completedTask = await Task.WhenAny(acceptTask, Task.Delay(1000, cancellationToken));
|
var completedTask = await Task.WhenAny(acceptTask, Task.Delay(1000, cancellationToken));
|
||||||
|
|
||||||
if (completedTask == acceptTask && !cancellationToken.IsCancellationRequested)
|
if (completedTask == acceptTask && !cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var client = await acceptTask;
|
var client = await acceptTask;
|
||||||
|
|
||||||
// Обработка клиента в отдельной задаче
|
// Обработка клиента в отдельной задаче
|
||||||
_ = Task.Run(async () => await HandleClient(client, cancellationToken));
|
_ = Task.Run(async () => await HandleClient(client, cancellationToken));
|
||||||
}
|
}
|
||||||
@@ -212,7 +230,7 @@ namespace f_srv
|
|||||||
{
|
{
|
||||||
// Чтение строки (до символа новой строки)
|
// Чтение строки (до символа новой строки)
|
||||||
var line = await reader.ReadLineAsync();
|
var line = await reader.ReadLineAsync();
|
||||||
|
|
||||||
if (line == null)
|
if (line == null)
|
||||||
{
|
{
|
||||||
// Клиент отключился
|
// Клиент отключился
|
||||||
|
|||||||
Reference in New Issue
Block a user