Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
run: dotnet build NetSdrClient.sln -c Release --no-restore
- name: Tests with coverage (OpenCover)
run: |
dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build `
dotnet test NetSdrClient.sln -c Release --no-build `
/p:CollectCoverage=true `
/p:CoverletOutput=TestResults/coverage.xml `
/p:CoverletOutputFormat=opencover
Expand Down
88 changes: 88 additions & 0 deletions EchoTcpServer/EchoServer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
namespace EchoTcpServer;

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
public class EchoServer
{
private readonly int _initialPort;
private TcpListener? _listener;
private readonly CancellationTokenSource _cancellationTokenSource;

public int Port => _listener?.LocalEndpoint is IPEndPoint ep ? ep.Port : _initialPort;

public EchoServer(int port)
{
_initialPort = port;
_cancellationTokenSource = new CancellationTokenSource();
}

public async Task StartAsync()
{
_listener = new TcpListener(IPAddress.Any, _initialPort);
_listener.Start();
Console.WriteLine($"Server started on port {Port}.");

while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
try
{
TcpClient client = await _listener.AcceptTcpClientAsync(_cancellationTokenSource.Token);
Console.WriteLine("Client connected.");

_ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token));
}
catch (OperationCanceledException)
{
break;
}
catch (ObjectDisposedException)
{
break;
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.OperationAborted)
{
break;
}
}

Console.WriteLine("Server shutdown.");
}

private static async Task HandleClientAsync(TcpClient client, CancellationToken token)
{
using (client)
using (NetworkStream stream = client.GetStream())
{
try
{
byte[] buffer = new byte[8192];
int bytesRead;

while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer.AsMemory(), token)) > 0)
{
await stream.WriteAsync(buffer.AsMemory(0, bytesRead), token);
Console.WriteLine($"Echoed {bytesRead} bytes to the client.");
}
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
Console.WriteLine("Client disconnected.");
}
}
}

public void Stop()
{
_cancellationTokenSource.Cancel();
_listener?.Stop();
_cancellationTokenSource.Dispose();
Console.WriteLine("Server stopped.");
}
}
File renamed without changes.
146 changes: 4 additions & 142 deletions EchoTcpServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,88 +1,10 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace EchoTcpServer;

using System;
using System.Threading.Tasks;

/// <summary>
/// This program was designed for test purposes only
/// Not for a review
/// </summary>
public class EchoServer
public static class Program
{
private readonly int _port;
private TcpListener _listener;
private CancellationTokenSource _cancellationTokenSource;


public EchoServer(int port)
{
_port = port;
_cancellationTokenSource = new CancellationTokenSource();
}

public async Task StartAsync()
{
_listener = new TcpListener(IPAddress.Any, _port);
_listener.Start();
Console.WriteLine($"Server started on port {_port}.");

while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
try
{
TcpClient client = await _listener.AcceptTcpClientAsync();
Console.WriteLine("Client connected.");

_ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token));
}
catch (ObjectDisposedException)
{
// Listener has been closed
break;
}
}

Console.WriteLine("Server shutdown.");
}

private async Task HandleClientAsync(TcpClient client, CancellationToken token)
{
using (NetworkStream stream = client.GetStream())
{
try
{
byte[] buffer = new byte[8192];
int bytesRead;

while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
{
// Echo back the received message
await stream.WriteAsync(buffer, 0, bytesRead, token);
Console.WriteLine($"Echoed {bytesRead} bytes to the client.");
}
}
catch (Exception ex) when (!(ex is OperationCanceledException))
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
client.Close();
Console.WriteLine("Client disconnected.");
}
}
}

public void Stop()
{
_cancellationTokenSource.Cancel();
_listener.Stop();
_cancellationTokenSource.Dispose();
Console.WriteLine("Server stopped.");
}

public static async Task Main(string[] args)
{
EchoServer server = new EchoServer(5000);
Expand Down Expand Up @@ -110,64 +32,4 @@ public static async Task Main(string[] args)
Console.WriteLine("Sender stopped.");
}
}
}


public class UdpTimedSender : IDisposable
{
private readonly string _host;
private readonly int _port;
private readonly UdpClient _udpClient;
private Timer _timer;

public UdpTimedSender(string host, int port)
{
_host = host;
_port = port;
_udpClient = new UdpClient();
}

public void StartSending(int intervalMilliseconds)
{
if (_timer != null)
throw new InvalidOperationException("Sender is already running.");

_timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds);
}

ushort i = 0;

private void SendMessageCallback(object state)
{
try
{
//dummy data
Random rnd = new Random();
byte[] samples = new byte[1024];
rnd.NextBytes(samples);
i++;

byte[] msg = (new byte[] { 0x04, 0x84 }).Concat(BitConverter.GetBytes(i)).Concat(samples).ToArray();
var endpoint = new IPEndPoint(IPAddress.Parse(_host), _port);

_udpClient.Send(msg, msg.Length, endpoint);
Console.WriteLine($"Message sent to {_host}:{_port} ");
}
catch (Exception ex)
{
Console.WriteLine($"Error sending message: {ex.Message}");
}
}

public void StopSending()
{
_timer?.Dispose();
_timer = null;
}

public void Dispose()
{
StopSending();
_udpClient.Dispose();
}
}
79 changes: 79 additions & 0 deletions EchoTcpServer/UdpTimedSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
namespace EchoTcpServer;

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Security.Cryptography;

public class UdpTimedSender : IDisposable
{
private readonly string _host;
private readonly int _port;
private readonly UdpClient _udpClient;
private Timer? _timer;
private ushort _messageIndex = 0;
private bool _disposed;

public UdpTimedSender(string host, int port)
{
_host = host;
_port = port;
_udpClient = new UdpClient();
}

public void StartSending(int intervalMilliseconds)
{
ObjectDisposedException.ThrowIf(_disposed, this);

if (_timer != null)
throw new InvalidOperationException("Sender is already running.");

_timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds);
}

private void SendMessageCallback(object? state)
{
try
{
byte[] samples = new byte[1024];
RandomNumberGenerator.Fill(samples);
_messageIndex++;

byte[] msg = [0x04, 0x84, .. BitConverter.GetBytes(_messageIndex), .. samples];
var endpoint = new IPEndPoint(IPAddress.Parse(_host), _port);

_udpClient.Send(msg, msg.Length, endpoint);
Console.WriteLine($"Message sent to {_host}:{_port}");
}
catch (Exception ex)
{
Console.WriteLine($"Error sending message: {ex.Message}");
}
}

public void StopSending()
{
_timer?.Dispose();
_timer = null;
}

protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
StopSending();
_udpClient.Dispose();
}
_disposed = true;
}
}

public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
Loading
Loading