Files
Client-Server-Apps/Server App/Program.cs
2026-04-10 23:05:59 +04:00

179 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class Server
{
private static Dictionary<TcpClient, string> clients = new Dictionary<TcpClient, string>();
private static Dictionary<string, List<string>> groups = new Dictionary<string, List<string>>();
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<string>();
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<string>();
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');
}
}