Files
LINUX/f-srv/Program.cs
2026-01-19 02:20:13 +07:00

409 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<TcpClient> _connectedClients = new List<TcpClient>();
private static bool _isRunning = false;
static async Task<int> Main(string[] args)
{
// Создание команды с аргументами
Option<IPAddress> ipOption = new("address", new[] { "--ip", "-i" })
{
Description = "IP адрес для прослушивания (по умолчанию: все интерфейсы)",
DefaultValueFactory = parseResult => IPAddress.Any
};
Option<int> 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);
}
}
}