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() { int port = 8888; TcpListener server = new TcpListener(IPAddress.Any, port); try { server.Start(); Console.WriteLine($"Сервер запущен на порту {port}"); while (true) { TcpClient client = server.AcceptTcpClient(); Thread clientThread = new Thread(HandleClient); clientThread.Start(client); } } catch (Exception e) { Console.WriteLine($"Ошибка: {e.Message}"); } finally { server.Stop(); } } 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("/groups")) { 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'); } }