Реализована запись полученных кадров в файл
This commit is contained in:
27
Client/FrameAssembler.cs
Normal file
27
Client/FrameAssembler.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Domain;
|
||||
|
||||
namespace Client;
|
||||
|
||||
public class FrameAssembler
|
||||
{
|
||||
private readonly Action<List<Data>> _frameCallback;
|
||||
private readonly List<Data> _buffer = new List<Data>();
|
||||
private const int FrameSize = 9;
|
||||
|
||||
public FrameAssembler(Action<List<Data>> frameCallback)
|
||||
{
|
||||
_frameCallback = frameCallback ?? throw new ArgumentNullException(nameof(frameCallback));
|
||||
}
|
||||
|
||||
public void AddData(Data data)
|
||||
{
|
||||
_buffer.Add(data);
|
||||
if (_buffer.Count >= FrameSize)
|
||||
{
|
||||
_frameCallback(new List<Data>(_buffer));
|
||||
_buffer.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ public class HttpClientWrapper : IClient
|
||||
private CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private Task? _runningTask;
|
||||
private Func<HttpResponseMessage, Task<Data?>>? _responseConverter;
|
||||
private Action<Domain.Data>? _callback;
|
||||
|
||||
public HttpClientWrapper(Func<HttpResponseMessage, Task<Data?>> responseConverter, string baseUrl = "http://localhost:5555/")
|
||||
{
|
||||
@@ -39,6 +40,11 @@ public class HttpClientWrapper : IClient
|
||||
_httpClient.Dispose();
|
||||
}
|
||||
|
||||
public void RegisterCallback(Action<Domain.Data> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
private async Task RunAsync(CancellationToken token)
|
||||
{
|
||||
long index = 0;
|
||||
@@ -68,6 +74,7 @@ public class HttpClientWrapper : IClient
|
||||
lastMs = sw.ElapsedMilliseconds;
|
||||
}
|
||||
//System.Console.WriteLine(data);
|
||||
_callback?.Invoke(data);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -4,4 +4,5 @@ interface IClient
|
||||
{
|
||||
public void Start();
|
||||
public void Stop();
|
||||
public void RegisterCallback(Action<Domain.Data> callback);
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
@@ -9,14 +11,32 @@ using Domain;
|
||||
using Domain.Dto;
|
||||
using MessagePack;
|
||||
|
||||
if (args.Length < 2)
|
||||
if (args.Length == 0 || args.Contains("--help") || args.Contains("-h"))
|
||||
{
|
||||
System.Console.WriteLine("Pass two args: http/tcp and json/bin");
|
||||
PrintHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args.Length < 2 || (args.Length > 2 && !args[2].StartsWith("--save-dir=")))
|
||||
{
|
||||
Console.WriteLine("Error: Insufficient arguments provided.");
|
||||
Console.WriteLine();
|
||||
PrintHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
var protocol = args[0];
|
||||
var serialization = args[1];
|
||||
string? saveDir = null;
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
saveDir = args[2].Substring("--save-dir=".Length);
|
||||
if (Directory.Exists(saveDir) == false)
|
||||
{
|
||||
System.Console.WriteLine("Save dir does not exist. Ignore.");
|
||||
}
|
||||
}
|
||||
|
||||
IClient? client = protocol switch
|
||||
{
|
||||
"http" => new HttpClientWrapper(serialization == "json" ? ConvertJsonResponse : ConvertMessagePackResponse),
|
||||
@@ -24,6 +44,17 @@ IClient? client = protocol switch
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (saveDir != null)
|
||||
{
|
||||
// Create FrameAssembler
|
||||
var frameAssembler = new FrameAssembler(frame =>
|
||||
{
|
||||
SaveFrame(frame, saveDir);
|
||||
});
|
||||
|
||||
client?.RegisterCallback(frameAssembler.AddData);
|
||||
}
|
||||
|
||||
client?.Start();
|
||||
System.Console.WriteLine("Client started:");
|
||||
System.Console.WriteLine(client);
|
||||
@@ -44,6 +75,44 @@ while (true)
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
static void PrintHelp()
|
||||
{
|
||||
Console.WriteLine("NetworkTest Client - A network testing client application");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("USAGE:");
|
||||
Console.WriteLine(" Client <protocol> <serialization> [--save-dir=<path>]");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("ARGUMENTS:");
|
||||
Console.WriteLine(" <protocol> The protocol to use:");
|
||||
Console.WriteLine(" - http: Connect using HTTP");
|
||||
Console.WriteLine(" - tcp: Connect using TCP");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" <serialization> The serialization format:");
|
||||
Console.WriteLine(" - json: Use JSON serialization");
|
||||
Console.WriteLine(" - bin: Use MessagePack binary serialization");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("OPTIONS:");
|
||||
Console.WriteLine(" --save-dir=<path> Directory to save received frames (optional)");
|
||||
Console.WriteLine(" --help, -h Show this help message");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("EXAMPLES:");
|
||||
Console.WriteLine(" Client http json");
|
||||
Console.WriteLine(" Client tcp bin --save-dir=./frames");
|
||||
Console.WriteLine(" Client --help");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("The client will connect to the server and start receiving data. Press Ctrl+C to stop.");
|
||||
}
|
||||
|
||||
static void SaveFrame(List<Data> frame, string saveDir)
|
||||
{
|
||||
var fileName = $"frame_{frame[0].FrameIndex}";
|
||||
fileName += ".json";
|
||||
var jsonDatas = frame.Select(d => new JsonData(d)).ToList();
|
||||
var options = new JsonSerializerOptions { WriteIndented = true };
|
||||
var json = JsonSerializer.Serialize(jsonDatas, options);
|
||||
File.WriteAllText(Path.Combine(saveDir, fileName), json);
|
||||
}
|
||||
|
||||
static async Task<Data?> ConvertJsonResponse(HttpResponseMessage response)
|
||||
{
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
|
||||
@@ -16,6 +16,7 @@ public class TcpClientWrapper : IClient
|
||||
private Task? _runningTask;
|
||||
private Func<byte[], Task<Data?>>? _responseConverter;
|
||||
private TcpClient? _tcpClient;
|
||||
private Action<Domain.Data>? _callback;
|
||||
|
||||
public TcpClientWrapper(Func<byte[], Task<Data?>> responseConverter, string host = "localhost", int port = 5555)
|
||||
{
|
||||
@@ -37,11 +38,37 @@ public class TcpClientWrapper : IClient
|
||||
_tcpClient?.Close();
|
||||
}
|
||||
|
||||
public void RegisterCallback(Action<Domain.Data> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
private async Task RunAsync(CancellationToken token)
|
||||
{
|
||||
const int maxRetries = 5;
|
||||
const int retryDelayMs = 1000;
|
||||
|
||||
for (int attempt = 1; attempt <= maxRetries; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
_tcpClient = new TcpClient();
|
||||
await _tcpClient.ConnectAsync(_host, _port, token);
|
||||
using (var stream = _tcpClient.GetStream())
|
||||
break; // Connection successful
|
||||
}
|
||||
catch (Exception ex) when (attempt < maxRetries)
|
||||
{
|
||||
Console.WriteLine($"Connection attempt {attempt} failed: {ex.Message}. Retrying in {retryDelayMs}ms...");
|
||||
await Task.Delay(retryDelayMs, token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to connect after {maxRetries} attempts: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
using (var stream = _tcpClient!.GetStream())
|
||||
{
|
||||
long index = 0;
|
||||
var sw = Stopwatch.StartNew();
|
||||
@@ -106,6 +133,7 @@ public class TcpClientWrapper : IClient
|
||||
lastMs = sw.ElapsedMilliseconds;
|
||||
}
|
||||
//Console.WriteLine(data);
|
||||
_callback?.Invoke(data);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -9,9 +9,17 @@ using NetworkTest;
|
||||
using Server;
|
||||
using Server.DataGenerator;
|
||||
|
||||
if (args.Length == 0 || args.Contains("--help") || args.Contains("-h"))
|
||||
{
|
||||
PrintHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args.Length < 3)
|
||||
{
|
||||
System.Console.WriteLine("Pass three args: test/http/tcp, json/bin, and random/predictable");
|
||||
Console.WriteLine("Error: Insufficient arguments provided.");
|
||||
Console.WriteLine();
|
||||
PrintHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -115,6 +123,43 @@ while (!cts.Token.IsCancellationRequested)
|
||||
return 0;
|
||||
|
||||
|
||||
static void PrintHelp()
|
||||
{
|
||||
Console.WriteLine("NetworkTest Server - A network testing server application");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("USAGE:");
|
||||
Console.WriteLine(" Server <protocol> <serialization> <generator> [delay]");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("ARGUMENTS:");
|
||||
Console.WriteLine(" <protocol> The protocol to use:");
|
||||
Console.WriteLine(" - test: Run serialization performance test mode");
|
||||
Console.WriteLine(" - http: Start HTTP server");
|
||||
Console.WriteLine(" - tcp: Start TCP server");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" <serialization> The serialization format:");
|
||||
Console.WriteLine(" - json: Use JSON serialization");
|
||||
Console.WriteLine(" - bin: Use MessagePack binary serialization");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" <generator> The data generator type:");
|
||||
Console.WriteLine(" - random: Generate random data");
|
||||
Console.WriteLine(" - predictable: Generate predictable data with optional delay");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" [delay] Optional delay in milliseconds for predictable generator");
|
||||
Console.WriteLine(" (only used when generator is 'predictable')");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("OPTIONS:");
|
||||
Console.WriteLine(" --help, -h Show this help message");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("EXAMPLES:");
|
||||
Console.WriteLine(" Server http json random");
|
||||
Console.WriteLine(" Server tcp bin predictable 1000");
|
||||
Console.WriteLine(" Server test json random");
|
||||
Console.WriteLine(" Server --help");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("The server will start and listen for connections. Press Ctrl+C to stop.");
|
||||
}
|
||||
|
||||
|
||||
void PrepareResponseJson(Data data, HttpListenerResponse response)
|
||||
{
|
||||
JsonData jsonData = new JsonData(data);
|
||||
|
||||
Reference in New Issue
Block a user