Подумываете о запуске клиент-серверного взаимодействия на C#, но не дается весь этот сетевой жаргон? Сегодня мы разберемся с ним, прибегнув к простому TCP — протоколу управления передачей. Сделаем так, чтобы приложения C# «общались» по сети, как старые друзья.
Создадим простую TCP-настройку клиента и сервера. Это как телефонный разговор двух человек: один — сервер, им звонки прослушиваются, другой — клиент, им звонок совершается.
Итак, погрузимся в мир TCP-коммуникаций с кодом и техническими нюансами, чтобы в ближайший перерыв на кофе не ударить в грязь лицом перед коллегами.
В чем прикол с этим TCP?
TCP — это как почта интернета. Сообщение здесь гарантированно доставляется адресату в правильной последовательности и без пропусков. TCP надежен и подключение-центричен. Он оптимален, когда нужно, чтобы получалось ровно то, что отправляется.
Подготовим сервер и клиент
Создадим на C# простой сервер для прослушивания соединений и клиент, который подключается для отправки сообщений. Сервер — это как кофейня, а клиент — кофеинозависимый, который отчаянно нуждается в утренней дозе.
Создадим сервер
Начнем с сервера. Он прослушивает входящие соединения, обрабатывая каждое отдельно. Вот код:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class SimpleServer
{
private TcpListener listener;
private List<TcpClient> clients = new List<TcpClient>(); // Отслеживаются подключенные клиенты
public void Start(int port)
{
listener = new TcpListener(IPAddress.Any, port);
listener.Start();
Console.WriteLine("Server started, waiting for connections...");
Thread acceptThread = new Thread(AcceptClients);
acceptThread.Start();
}
private void AcceptClients()
{
while (true)
{
try
{
TcpClient client = listener.AcceptTcpClient();
clients.Add(client);
Console.WriteLine("Client connected.");
Thread clientThread = new Thread(() => HandleClient(client));
clientThread.Start();
}
catch (Exception ex)
{
Console.WriteLine("Error accepting client: " + ex.Message);
}
}
}
private void HandleClient(TcpClient client)
{
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024];
int bytesRead;
try
{
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received: " + message);
// Сообщение возвращается клиенту
byte[] response = Encoding.UTF8.GetBytes("Echo: " + message);
stream.Write(response, 0, response.Length);
}
}
catch (Exception ex)
{
Console.WriteLine("Error communicating with client: " + ex.Message);
}
finally
{
stream.Close();
client.Close();
clients.Remove(client);
Console.WriteLine("Client disconnected.");
}
}
}
class Program
{
static void Main()
{
SimpleServer server = new SimpleServer();
server.Start(5000); // Выбирается порт, любой
}
}
Принцип работы
TcpListener
— это «уши» сервера, ими прослушиваются входящие соединения.- У каждого клиентского соединения собственный поток — сервер не зависнет в ожидании клиента. Многозадачность во всей красе!
- Сервером сообщения возвращаются клиенту. Схема простая, зато рабочая.
Теперь создадим клиента
На стороне клиента все чуть проще. Клиент подключается к серверу, отправляет сообщение, а затем с нетерпением ожидает ответа сервера:
using System;
using System.Net.Sockets;
using System.Text;
public class SimpleClient
{
private TcpClient client;
private NetworkStream stream;
public void ConnectToServer(string ipAddress, int port)
{
client = new TcpClient(ipAddress, port);
stream = client.GetStream();
Console.WriteLine("Connected to the server.");
// Начинается считывание сообщений в фоновом режиме
ReadMessages();
}
private void ReadMessages()
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine("Server says: " + message);
}
}
public void SendMessage(string message)
{
if (stream != null && stream.CanWrite)
{
byte[] data = Encoding.UTF8.GetBytes(message);
stream.Write(data, 0, data.Length);
Console.WriteLine("Message sent: " + message);
}
}
}
class Program
{
static void Main()
{
SimpleClient client = new SimpleClient();
client.ConnectToServer("127.0.0.1", 5000); // Подключение к локальной машине
Console.WriteLine("Type a message to send:");
string message = Console.ReadLine();
client.SendMessage(message);
}
}
Вкратце о клиенте
- Клиент подключается к серверу с помощью
TcpClient
, как при входе в личные сообщения на сервере. - Сообщения отправляются через
NetworkStream
, ответы считываются из того же потока. - Это как портативная рация: нажимаешь — говоришь, отпускаешь — слушаешь.
Заключение
Вот и все. Простой клиент-сервер TCP на C# готов. Награду за сложность не получит, но работу выполнит на отлично. Это основа для продвинутых сетевых приложений. Создаете чат, многопользовательскую игру или просто хотите взаимодействия двух программ, TCP — ваш надежный друг. Не забывайте делать потоки чистыми, корректно обрабатывать исключения и никогда не доверять данным, пока не проверили их.
Читайте также:
- Подробное знакомство с кортежами в C#
- .NET Aspire — стремление к рациональному подходу в сфере облачной разработки
- Как вызвать из C# генерируемую на Rust библиотеку
Читайте нас в Telegram, VK и Дзен
Перевод статьи Jean-Michel KEULEYAN: C# — TCP Communications: Building a Client-Server Chat