Skip to content
Open
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
63 changes: 39 additions & 24 deletions EchoTspServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,14 @@
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;

/// <summary>
/// This program was designed for test purposes only
/// Not for a review
/// </summary>
namespace EchoTspServer
{

public class EchoServer
{
private readonly int _port;
private TcpListener? _listener;
private readonly CancellationTokenSource _cancellationTokenSource;


public EchoServer(int port)
{
_port = port;
Expand All @@ -43,8 +37,7 @@
}
catch (ObjectDisposedException)
{
// Listener has been closed
break;
break; // Listener has been closed
}
}

Expand All @@ -61,10 +54,11 @@
byte[] buffer = new byte[8192];
int bytesRead;

while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
while (!token.IsCancellationRequested &&
(bytesRead = await stream.ReadAsync(buffer.AsMemory(0, buffer.Length), token)) > 0)
{
// Echo back the received message
await stream.WriteAsync(buffer, 0, bytesRead, token);
await stream.WriteAsync(buffer.AsMemory(0, bytesRead), token);
Console.WriteLine($"Echoed {bytesRead} bytes to the client.");
}
}
Expand All @@ -83,21 +77,20 @@
public void Stop()
{
_cancellationTokenSource.Cancel();
_listener.Stop();
_listener?.Stop();
_cancellationTokenSource.Dispose();
Console.WriteLine("Server stopped.");
}

public static async Task Main(string[] args)

Check warning on line 85 in EchoTspServer/Program.cs

View workflow job for this annotation

GitHub Actions / Sonar Check

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
EchoServer server = new EchoServer(5000);

// Start the server in a separate task
_ = Task.Run(() => server.StartAsync());

string host = "127.0.0.1"; // Target IP
int port = 60000; // Target Port
int intervalMilliseconds = 5000; // Send every 3 seconds
string host = "127.0.0.1";
int port = 60000;
int intervalMilliseconds = 5000;

using (var sender = new UdpTimedSender(host, port))
{
Expand All @@ -106,8 +99,7 @@

Console.WriteLine("Press 'q' to quit...");
while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q)
{

Check warning on line 102 in EchoTspServer/Program.cs

View workflow job for this annotation

GitHub Actions / Sonar Check

Either remove or fill this block of code. (https://rules.sonarsource.com/csharp/RSPEC-108)
// Just wait until 'q' is pressed
}

sender.StopSending();
Expand All @@ -117,13 +109,15 @@
}
}


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

private ushort i = 0;

public UdpTimedSender(string host, int port)
{
Expand All @@ -140,19 +134,22 @@
_timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds);
}

ushort i = 0;

private void SendMessageCallback(object state)
private void SendMessageCallback(object? state)
{
if (_disposed) return;

try
{
//dummy data
Random rnd = new Random();

Check warning on line 143 in EchoTspServer/Program.cs

View workflow job for this annotation

GitHub Actions / Sonar Check

Make sure that using this pseudorandom number generator is safe here. (https://rules.sonarsource.com/csharp/RSPEC-2245)
byte[] samples = new byte[1024];
rnd.NextBytes(samples);
i++;

byte[] msg = (new byte[] { 0x04, 0x84 }).Concat(BitConverter.GetBytes(i)).Concat(samples).ToArray();
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);
Expand All @@ -170,11 +167,29 @@
_timer = null;
}

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

_disposed = true;
}
}

public void Dispose()
{
StopSending();
_udpClient.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}

~UdpTimedSender()
{
Dispose(false);
}
}
}
Loading