Files
NetworkTest/Server/TcpServer.cs
Пытков Роман c21c92db37 Добавлен magic-header
2025-09-17 12:39:49 +03:00

89 lines
2.6 KiB
C#

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 const uint MagicHeader = 0xDEADBEEF;
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 magicBytes = BitConverter.GetBytes(MagicHeader);
var lengthBytes = BitConverter.GetBytes(bytes.Length);
await stream.WriteAsync(magicBytes, 0, magicBytes.Length, token);
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}";
}
}