Добавлен транспорт TCP

This commit is contained in:
Пытков Роман
2025-09-17 11:07:45 +03:00
parent bbe5a75dba
commit 095726786d
5 changed files with 317 additions and 10 deletions

View File

@@ -63,32 +63,40 @@ if (protocol == "test")
}
}
IServer? server = protocol == "http" ?
new HttpServer(index => dataGenerator.GetPackage(index),
serialization == "json" ? PrepareResponseJson : PrepareResponseMessagePack) :
null;
IServer? server = protocol switch
{
"http" => new HttpServer(index => dataGenerator.GetPackage(index),
serialization == "json" ? PrepareResponseJson : PrepareResponseMessagePack),
"tcp" => new TcpServer(index => dataGenerator.GetPackage(index),
serialization == "json" ? PrepareBytesJson : PrepareBytesMessagePack),
_ => null
};
server?.Start();
System.Console.WriteLine("Server started:");
System.Console.WriteLine(server);
// Создаем CancellationTokenSource для управления остановкой
var cts = new CancellationTokenSource();
// Обработка выхода по Ctrl+C
Console.CancelKeyPress += (sender, e) =>
{
e.Cancel = true; // Prevent immediate termination
Console.WriteLine("Shutdown signal received. Stopping server...");
cts.Cancel();
server?.Stop();
Console.WriteLine("Goodbye!");
Environment.Exit(0);
};
// Бесконечный цикл ожидания
while (true)
// Бесконечный цикл ожидания с возможностью прерывания
while (!cts.Token.IsCancellationRequested)
{
Thread.Sleep(1000);
cts.Token.WaitHandle.WaitOne(1000);
}
return 0;
void PrepareResponseJson(Data data, HttpListenerResponse response)
{
@@ -109,3 +117,16 @@ void PrepareResponseMessagePack(Data data, HttpListenerResponse response)
response.OutputStream.Write(buffer, 0, buffer.Length);
}
static byte[] PrepareBytesJson(Data data)
{
JsonData jsonData = new JsonData(data);
var responseText = JsonSerializer.Serialize(jsonData);
return Encoding.UTF8.GetBytes(responseText);
}
static byte[] PrepareBytesMessagePack(Data data)
{
MessagePackData msgPackData = new MessagePackData(data);
return MessagePackSerializer.Serialize(msgPackData);
}

86
Server/TcpServer.cs Normal file
View File

@@ -0,0 +1,86 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Domain;
namespace NetworkTest;
public class TcpServer : IServer
{
private readonly TcpListener _listener;
private readonly Func<long, Data?> _getData;
private readonly Func<Data, byte[]> _prepareBytes;
private readonly int _port;
private CancellationTokenSource _cts = new CancellationTokenSource();
public TcpServer(Func<long, Data?> getData, Func<Data, byte[]> prepareBytes, int port = 5555)
{
_getData = getData;
_prepareBytes = prepareBytes;
_port = port;
_listener = new TcpListener(IPAddress.Any, _port);
}
public void Start()
{
_cts = new CancellationTokenSource();
_listener.Start();
Task.Run(() => ListenAsync(_cts.Token));
}
public void Stop()
{
_cts.Cancel();
_listener.Stop();
}
private async Task ListenAsync(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
var client = await _listener.AcceptTcpClientAsync(token);
_ = Task.Run(() => HandleClientAsync(client, token));
}
catch (SocketException)
{
break;
}
catch (OperationCanceledException)
{
break;
}
}
}
private async Task HandleClientAsync(TcpClient client, CancellationToken token)
{
using (client)
using (var stream = client.GetStream())
{
var index = 0L;
while (!token.IsCancellationRequested && client.Connected)
{
var data = _getData(index);
if (data != null)
{
var bytes = _prepareBytes(data);
var lengthBytes = BitConverter.GetBytes(bytes.Length);
await stream.WriteAsync(lengthBytes, 0, lengthBytes.Length, token);
await stream.WriteAsync(bytes, 0, bytes.Length, token);
index++;
}
// await Task.Delay(50, token); // Removed delay to test maximum throughput
}
}
}
public override string ToString()
{
return $"TcpServer listening on port {_port}";
}
}