Перейти к основному содержимому

Простой консольный чат на C#

Простой консольный чат на C#

Простой консольный чат на C# — это учебное приложение, демонстрирующее базовые принципы сетевого взаимодействия между клиентом и сервером с использованием сокетов. Такое приложение помогает понять основы TCP-коммуникации, многопоточности и обработки входящих сообщений в реальном времени.

Архитектура приложения

Приложение состоит из двух компонентов:

  • Сервер — принимает подключения от клиентов, пересылает полученные сообщения всем подключённым участникам.
  • Клиент — подключается к серверу, отправляет текстовые сообщения и выводит полученные сообщения в консоль.

Оба компонента реализованы как консольные приложения на языке C# с использованием стандартной библиотеки System.Net.Sockets.


Сервер

Сервер использует TcpListener для прослушивания входящих соединений на заданном порту (например, 8888). Для каждого клиента создаётся отдельный поток, который читает входящие сообщения и рассылает их всем остальным подключённым клиентам.

using Система;
using Система.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using Система.Text;
using Система.Threading;

class ChatServer
{
private static readonly List<TcpClient> clients = new();
private const int Port = 8888;

static void Main()
{
TcpListener server = new(IPAddress.Any, Port);
server.Start();
Console.WriteLine($"Сервер запущен на порту {Port}.");

while (true)
{
TcpClient client = server.AcceptTcpClient();
lock (clients)
{
clients.Add(client);
}
Console.WriteLine("Новый клиент подключился.");
Thread clientThread = new(HandleClient);
clientThread.Start(client);
}
}

static void HandleClient(object obj)
{
TcpClient client = (TcpClient)obj;
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024];

while (client.Connected)
{
try
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0) break;

string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"Получено: {message}");

BroadcastMessage(message, client);
}
catch
{
break;
}
}

lock (clients)
{
clients.Remove(client);
}
client.Close();
Console.WriteLine("Клиент отключился.");
}

static void BroadcastMessage(string message, TcpClient sender)
{
lock (clients)
{
foreach (TcpClient client in clients)
{
if (client != sender && client.Connected)
{
try
{
byte[] Данные = Encoding.UTF8.GetBytes(message);
client.GetStream().Write(Данные, 0, Данные.Length);
}
catch
{
// Игнорируем ошибки при отправке
}
}
}
}
}
}

Клиент

Клиент подключается к серверу по адресу 127.0.0.1 и порту 8888. Он запускает два потока:

  • Один читает сообщения от сервера и выводит их в консоль.
  • Другой ожидает ввода от пользователя и отправляет его на сервер.
using Система;
using System.Net.Sockets;
using Система.Text;
using Система.Threading;

class ChatClient
{
static TcpClient client;
static NetworkStream stream;

static void Main()
{
try
{
client = new TcpClient("127.0.0.1", 8888);
stream = client.GetStream();
Console.WriteLine("Подключено к чату. Введите своё имя:");

string username = Console.ReadLine() ?? "Аноним";
Send($"{username} присоединился к чату.");

Thread receiveThread = new(ReceiveMessages);
receiveThread.Start();

while (true)
{
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input)) continue;

Send($"{username}: {input}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка подключения: {ex.Message}");
}
}

static void ReceiveMessages()
{
byte[] buffer = new byte[1024];
while (client.Connected)
{
try
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0) break;

string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine(message);
}
catch
{
break;
}
}
}

static void Send(string message)
{
try
{
byte[] Данные = Encoding.UTF8.GetBytes(message);
stream.Write(Данные, 0, Данные.Length);
}
catch
{
Console.WriteLine("Не удалось отправить сообщение.");
}
}
}

Как использовать

  1. Запустите ChatServer.exe — сервер начнёт ожидать подключений.
  2. Запустите один или несколько экземпляров ChatClient.exe.
  3. Введите имя при первом запуске клиента.
  4. Пишите сообщения — они будут видны всем участникам чата.

Особенности реализации

  • Кодировка: используется UTF-8 для корректной передачи кириллицы и специальных символов.
  • Потокобезопасность: список клиентов защищён блокировкой lock, чтобы избежать гонок при одновременном доступе из разных потоков.
  • Обработка отключения: при разрыве соединения клиент удаляется из списка, и сервер продолжает работать.
  • Минимализм: нет авторизации, шифрования или хранения истории — только базовая функциональность.

Возможные улучшения

  • Добавление уникальных идентификаторов пользователей.
  • Поддержка команд (/exit, /users).
  • Шифрование трафика через TLS.
  • Сохранение истории чата.
  • Графический интерфейс с использованием WPF или MAUI.

См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).