From 3d5c98ce1d1b760314712a1c32267ad4c4acc007 Mon Sep 17 00:00:00 2001 From: KhasanovAMdev Date: Thu, 9 Apr 2026 23:03:38 +0400 Subject: [PATCH] update --- Client App/Program.cs | 96 +++++++++++++++++++++---- Server App/Program.cs | 159 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 224 insertions(+), 31 deletions(-) diff --git a/Client App/Program.cs b/Client App/Program.cs index a2db0b6..e0ae5c5 100644 --- a/Client App/Program.cs +++ b/Client App/Program.cs @@ -1,36 +1,106 @@ using System; using System.Net.Sockets; using System.Text; +using System.Threading; class Client { + private static TcpClient client; + private static NetworkStream stream; + private static string currentGroup = "all"; + static void Main() { - TcpClient client = new TcpClient(); + Console.Write("Введите ваше имя: "); + string name = Console.ReadLine(); + + string serverIp = "127.0.0.1"; + int port = 8888; try { - client.Connect("127.0.0.1", 8888); - NetworkStream stream = client.GetStream(); + client = new TcpClient(); + client.Connect(serverIp, port); + stream = client.GetStream(); - Console.Write("Текст: "); - string text = Console.ReadLine(); + // Отправляем имя + byte[] nameData = Encoding.UTF8.GetBytes(name); + stream.Write(nameData, 0, nameData.Length); - byte[] data = Encoding.UTF8.GetBytes(text); - stream.Write(data, 0, data.Length); + Console.WriteLine($"Добро пожаловать, {name}!"); - data = new byte[1024]; - int bytes = stream.Read(data, 0, data.Length); - string response = Encoding.UTF8.GetString(data, 0, bytes); + // Поток для приема сообщений + Thread receiveThread = new Thread(ReceiveMessages); + receiveThread.Start(); - Console.WriteLine($"Ответ: {response}"); + // Циклическая отправка сообщений + while (true) + { + Console.Write($"[Группа: {currentGroup}] Введите сообщение: "); + string text = Console.ReadLine(); - stream.Close(); - client.Close(); + if (text.ToLower() == "exit") + break; + else if (text.StartsWith("/join ")) + { + currentGroup = text.Substring(6); + string command = $"/group {currentGroup}"; + byte[] data = Encoding.UTF8.GetBytes(command); + stream.Write(data, 0, data.Length); + } + else if (text.StartsWith("/groups")) + { + // Запрос списка групп и клиентов + byte[] data = Encoding.UTF8.GetBytes("/list"); + stream.Write(data, 0, data.Length); + } + else + { + string message = $"/msg {currentGroup} {text}"; + byte[] data = Encoding.UTF8.GetBytes(message); + stream.Write(data, 0, data.Length); + } + } } catch (Exception e) { Console.WriteLine($"Ошибка: {e.Message}"); } + finally + { + stream?.Close(); + client?.Close(); + } + } + + private static void ReceiveMessages() + { + byte[] buffer = new byte[4096]; + try + { + while (true) + { + int bytes = stream.Read(buffer, 0, buffer.Length); + if (bytes == 0) break; + + string response = Encoding.UTF8.GetString(buffer, 0, bytes); + + if (response.StartsWith("/clients ")) + { + Console.WriteLine($"\n=== Список клиентов и групп ==="); + Console.WriteLine(response.Substring(9)); + Console.WriteLine("================================"); + } + else + { + Console.WriteLine($"\n[Сообщение]: {response}"); + } + Console.Write($"[Группа: {currentGroup}] Введите сообщение: "); + } + } + catch + { + Console.WriteLine("\nСоединение с сервером потеряно"); + } } } \ No newline at end of file diff --git a/Server App/Program.cs b/Server App/Program.cs index 2a81596..aa70367 100644 --- a/Server App/Program.cs +++ b/Server App/Program.cs @@ -1,35 +1,31 @@ -using System.Net; +using System; +using System.Collections.Generic; +using System.Net; using System.Net.Sockets; using System.Text; +using System.Threading; class Server { + private static Dictionary clients = new Dictionary(); + private static Dictionary> groups = new Dictionary>(); + private static readonly object lockObj = new object(); + static void Main() { - TcpListener server = new TcpListener(IPAddress.Any, 8888); + int port = 8888; + TcpListener server = new TcpListener(IPAddress.Any, port); try { server.Start(); - Console.WriteLine("Сервер запущен"); + Console.WriteLine($"Сервер запущен на порту {port}"); while (true) { TcpClient client = server.AcceptTcpClient(); - NetworkStream stream = client.GetStream(); - - byte[] buffer = new byte[1024]; - int bytes = stream.Read(buffer, 0, buffer.Length); - - string text = Encoding.UTF8.GetString(buffer, 0, bytes); - Console.WriteLine($"Получено: {text}"); - - string response = $"OK: {StrProc(text)}"; - byte[] data = Encoding.UTF8.GetBytes(response); - stream.Write(data, 0, data.Length); - - stream.Close(); - client.Close(); + Thread clientThread = new Thread(HandleClient); + clientThread.Start(client); } } catch (Exception e) @@ -42,7 +38,134 @@ class Server } } - //18 вариант + private static void HandleClient(object obj) + { + TcpClient client = (TcpClient)obj; + NetworkStream stream = client.GetStream(); + byte[] buffer = new byte[1024]; + + try + { + // Получаем имя клиента + int bytes = stream.Read(buffer, 0, buffer.Length); + string clientName = Encoding.UTF8.GetString(buffer, 0, bytes); + + lock (lockObj) + { + clients[client] = clientName; + if (!groups.ContainsKey("all")) + groups["all"] = new List(); + groups["all"].Add(clientName); + } + + Console.WriteLine($"Клиент {clientName} подключился"); + + // Отправляем список клиентов + SendClientList(stream); + + // Основной цикл приема сообщений + while (true) + { + bytes = stream.Read(buffer, 0, buffer.Length); + if (bytes == 0) break; + + string message = Encoding.UTF8.GetString(buffer, 0, bytes); + Console.WriteLine($"Получено от {clientName}: {message}"); + + // Обработка команд + if (message.StartsWith("/group ")) + { + string groupName = message.Substring(7); + HandleGroupCommand(clientName, groupName); + SendClientList(stream); + } + else if (message.StartsWith("/msg ")) + { + string[] parts = message.Substring(5).Split(' ', 2); + if (parts.Length == 2) + { + string targetGroup = parts[0]; + string msgText = parts[1]; + string processed = StrProc(msgText); + SendToGroup(targetGroup, $"{clientName}: {processed}"); + } + } + } + } + catch + { + // Клиент отключился + } + finally + { + lock (lockObj) + { + string name = clients[client]; + Console.WriteLine($"Клиент {name} отключился"); + + // Удаляем из всех групп + foreach (var group in groups.Values) + { + group.Remove(name); + } + clients.Remove(client); + } + client.Close(); + } + } + + private static void HandleGroupCommand(string clientName, string groupName) + { + lock (lockObj) + { + if (!groups.ContainsKey(groupName)) + groups[groupName] = new List(); + + if (!groups[groupName].Contains(clientName)) + groups[groupName].Add(clientName); + + Console.WriteLine($"{clientName} присоединился к группе {groupName}"); + } + } + + private static void SendClientList(NetworkStream stream) + { + lock (lockObj) + { + string list = "/clients "; + foreach (var group in groups) + { + list += $"[{group.Key}: {string.Join(", ", group.Value)}] "; + } + byte[] data = Encoding.UTF8.GetBytes(list); + stream.Write(data, 0, data.Length); + } + } + + private static void SendToGroup(string groupName, string message) + { + lock (lockObj) + { + if (!groups.ContainsKey(groupName)) return; + + byte[] data = Encoding.UTF8.GetBytes(message); + + foreach (var client in clients) + { + if (groups[groupName].Contains(client.Value)) + { + try + { + NetworkStream stream = client.Key.GetStream(); + stream.Write(data, 0, data.Length); + } + catch { } + } + } + } + } + + // Вариант 18: замена 'y' на 'o' private static string StrProc(string str) { return str.Replace('y', 'o');