238 lines
8.9 KiB
C#
238 lines
8.9 KiB
C#
using System;
|
||
using System.CommandLine;
|
||
using System.CommandLine.Parsing;
|
||
using System.IO;
|
||
using System.Net.Sockets;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace f_cln
|
||
{
|
||
class Program
|
||
{
|
||
static async Task<int> Main(string[] args)
|
||
{
|
||
// Создание команды с аргументами
|
||
Option<string> ipOption = new("address", new[] { "--ip", "-i" })
|
||
{
|
||
Description = "IP адрес сервера (по умолчанию: localhost)",
|
||
DefaultValueFactory = parseResult => "localhost"
|
||
};
|
||
|
||
Option<int> portOption = new("port", new[] { "--port", "-p" })
|
||
{
|
||
Description = "Порт сервера (по умолчанию: 1771)",
|
||
DefaultValueFactory = parseResult => 1771
|
||
};
|
||
|
||
Option<string?> messageOption = new("message", new[] { "--message", "-m" })
|
||
{
|
||
Description = "Сообщение для отправки (если не указано, работает в интерактивном режиме)",
|
||
Arity = ArgumentArity.ZeroOrOne
|
||
};
|
||
|
||
var rootCommand = new RootCommand("Клиент для отправки строк серверу и получения их в обратном порядке")
|
||
{
|
||
ipOption,
|
||
portOption,
|
||
messageOption
|
||
};
|
||
|
||
ParseResult parseResult = rootCommand.Parse(args);
|
||
if (parseResult.Errors.Count == 0)
|
||
{
|
||
string ip = parseResult.GetValue(ipOption) ?? "localhost";
|
||
int port = parseResult.GetValue(portOption);
|
||
string? message = parseResult.GetValue(messageOption);
|
||
|
||
try
|
||
{
|
||
if (!string.IsNullOrEmpty(message))
|
||
{
|
||
// Режим однократной отправки
|
||
return await SendMessage(ip, port, message);
|
||
}
|
||
else
|
||
{
|
||
// Интерактивный режим
|
||
return await RunInteractive(ip, port);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.Error.WriteLine($"Ошибка: {ex.Message}");
|
||
return 2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
foreach (ParseError parseError in parseResult.Errors)
|
||
{
|
||
Console.Error.WriteLine(parseError.Message);
|
||
}
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
static async Task<int> SendMessage(string ip, int port, string message)
|
||
{
|
||
Console.WriteLine($"Подключение к {ip}:{port}...");
|
||
|
||
using var client = new TcpClient();
|
||
await client.ConnectAsync(ip, port);
|
||
|
||
Console.WriteLine("Подключено к серверу");
|
||
|
||
using var stream = client.GetStream();
|
||
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||
using var writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
|
||
|
||
// Читаем приветственное сообщение
|
||
var welcomeMessage = await reader.ReadLineAsync();
|
||
if (welcomeMessage != null && welcomeMessage.StartsWith("hello "))
|
||
{
|
||
var clientAddress = welcomeMessage[6..];
|
||
Console.WriteLine($"Ваш адрес: {clientAddress}");
|
||
}
|
||
|
||
// Очистка сообщения
|
||
string cleanedMessage = CleanInput(message);
|
||
Console.WriteLine();
|
||
|
||
// Отправка сообщения
|
||
await writer.WriteLineAsync(cleanedMessage);
|
||
Console.WriteLine($"Отправлено: {cleanedMessage}");
|
||
|
||
// Чтение ответа
|
||
var response = await reader.ReadLineAsync();
|
||
|
||
if (response != null)
|
||
{
|
||
string cleanedResponse = CleanInput(response);
|
||
Console.WriteLine($"Ответ: {cleanedResponse}");
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("Сервер не ответил");
|
||
return 2;
|
||
}
|
||
}
|
||
|
||
static async Task<int> RunInteractive(string ip, int port)
|
||
{
|
||
Console.WriteLine($"Подключение к {ip}:{port}...");
|
||
|
||
using var client = new TcpClient();
|
||
await client.ConnectAsync(ip, port);
|
||
|
||
Console.WriteLine("Подключено к серверу");
|
||
|
||
using var stream = client.GetStream();
|
||
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||
using var writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
|
||
|
||
// Читаем приветственное сообщение
|
||
var welcomeMessage = await reader.ReadLineAsync();
|
||
if (welcomeMessage != null && welcomeMessage.StartsWith("hello "))
|
||
{
|
||
var clientAddress = welcomeMessage[6..];
|
||
Console.WriteLine($"Ваш адрес: {clientAddress}");
|
||
}
|
||
|
||
Console.WriteLine(); // Пустая строка для единообразия
|
||
PrintHelp();
|
||
|
||
while (true)
|
||
{
|
||
try
|
||
{
|
||
Console.Write("> ");
|
||
var input = Console.ReadLine();
|
||
|
||
if (string.IsNullOrWhiteSpace(input))
|
||
continue;
|
||
|
||
// Очистка ввода от непечатаемых символов и BOM
|
||
input = CleanInput(input);
|
||
|
||
if (string.IsNullOrEmpty(input))
|
||
continue;
|
||
|
||
if (input.Equals("exit", StringComparison.OrdinalIgnoreCase) ||
|
||
input.Equals("quit", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
Console.WriteLine("Завершение работы...");
|
||
break;
|
||
}
|
||
|
||
if (input.Equals("help", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
PrintHelp();
|
||
continue;
|
||
}
|
||
|
||
// Отправка сообщения
|
||
await writer.WriteLineAsync(input);
|
||
Console.WriteLine($"Отправлено: {input}");
|
||
|
||
// Чтение ответа
|
||
var response = await reader.ReadLineAsync();
|
||
|
||
if (response != null)
|
||
{
|
||
// Очистка ответа от непечатаемых символов
|
||
response = CleanInput(response);
|
||
Console.WriteLine($"Ответ: {response}");
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("Сервер отключился");
|
||
return 2;
|
||
}
|
||
}
|
||
catch (Exception ex) when (ex is IOException || ex is ObjectDisposedException)
|
||
{
|
||
Console.WriteLine("Соединение с сервером разорвано");
|
||
return 2;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"Ошибка: {ex.Message}");
|
||
return 2;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// Метод для очистки строки от непечатаемых символов
|
||
static string CleanInput(string input)
|
||
{
|
||
if (string.IsNullOrEmpty(input))
|
||
return input;
|
||
|
||
// Удаляем BOM (U+FEFF) и другие непечатаемые символы
|
||
var result = new StringBuilder();
|
||
foreach (char c in input)
|
||
{
|
||
// Оставляем только печатаемые символы и пробелы
|
||
if (!char.IsControl(c) || c == '\n' || c == '\r' || c == '\t')
|
||
{
|
||
result.Append(c);
|
||
}
|
||
}
|
||
|
||
return result.ToString().Trim();
|
||
}
|
||
|
||
static void PrintHelp()
|
||
{
|
||
Console.WriteLine("\n=== Команды клиента ===");
|
||
Console.WriteLine(" Просто введите текст для отправки на сервер");
|
||
Console.WriteLine(" exit или quit - завершить работу");
|
||
Console.WriteLine(" help - показать эту справку");
|
||
Console.WriteLine("========================\n");
|
||
}
|
||
}
|
||
} |