Skip to content
Open

Lab1 #67

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
8 changes: 4 additions & 4 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ name: SonarCloud analysis

on:
push:
branches: [ "master" ]
branches: [ "main" ]
pull_request:
branches: [ "master" ]
branches: [ "main" ]
workflow_dispatch:

permissions:
Expand All @@ -56,8 +56,8 @@ jobs:
dotnet tool install --global dotnet-sonarscanner
echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH
dotnet sonarscanner begin `
/k:"ppanchen_NetSdrClient" `
/o:"ppanchen" `
/k:"LeVanchua_-" `
/o:"levanchua" `
/d:sonar.token="${{ secrets.SONAR_TOKEN }}" `
/d:sonar.cs.opencover.reportsPaths="**/coverage.xml" `
/d:sonar.cpd.cs.minimumTokens=40 `
Expand Down
249 changes: 124 additions & 125 deletions EchoTspServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,169 +5,168 @@
using System.Threading;
using System.Threading.Tasks;

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


public EchoServer(int port)
public class EchoServer
{
_port = port;
_cancellationTokenSource = new CancellationTokenSource();
}
private readonly int _port;
private TcpListener _listener;
private CancellationTokenSource _cancellationTokenSource;

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

while (!_cancellationTokenSource.Token.IsCancellationRequested)
public async Task StartAsync()
{
try
{
TcpClient client = await _listener.AcceptTcpClientAsync();
Console.WriteLine("Client connected.");
_listener = new TcpListener(IPAddress.Any, _port);
_listener.Start();
Console.WriteLine($"Server started on port {_port}.");

_ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token));
}
catch (ObjectDisposedException)
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
// Listener has been closed
break;
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.");
}
Console.WriteLine("Server shutdown.");
}

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

while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
try
{
// Echo back the received message
await stream.WriteAsync(buffer, 0, bytesRead, token);
Console.WriteLine($"Echoed {bytesRead} bytes to the client.");
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.");
}
}
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);
public void Stop()
{
_cancellationTokenSource.Cancel();
_listener.Stop();
_cancellationTokenSource.Dispose();
Console.WriteLine("Server stopped.");
}

// Start the server in a separate task
_ = Task.Run(() => server.StartAsync());
public static async Task Main(string[] args)
{
EchoServer server = new EchoServer(5000);

string host = "127.0.0.1"; // Target IP
int port = 60000; // Target Port
int intervalMilliseconds = 5000; // Send every 3 seconds
// Start the server in a separate task
_ = Task.Run(() => server.StartAsync());

using (var sender = new UdpTimedSender(host, port))
{
Console.WriteLine("Press any key to stop sending...");
sender.StartSending(intervalMilliseconds);
string host = "127.0.0.1"; // Target IP
int port = 60000; // Target Port
int intervalMilliseconds = 5000; // Send every 3 seconds

Console.WriteLine("Press 'q' to quit...");
while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q)
using (var sender = new UdpTimedSender(host, port))
{
// Just wait until 'q' is pressed
}
Console.WriteLine("Press any key to stop sending...");
sender.StartSending(intervalMilliseconds);

sender.StopSending();
server.Stop();
Console.WriteLine("Sender stopped.");
Console.WriteLine("Press 'q' to quit...");
while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q)
{
// Just wait until 'q' is pressed
}

sender.StopSending();
server.Stop();
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)
public class UdpTimedSender : IDisposable
{
_host = host;
_port = port;
_udpClient = new UdpClient();
}
private readonly string _host;
private readonly int _port;
private readonly UdpClient _udpClient;
private Timer _timer;

public void StartSending(int intervalMilliseconds)
{
if (_timer != null)
throw new InvalidOperationException("Sender is already running.");
public UdpTimedSender(string host, int port)
{
_host = host;
_port = port;
_udpClient = new UdpClient();
}

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

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

private void SendMessageCallback(object state)
{
try
ushort i = 0;

private void SendMessageCallback(object state)
{
//dummy data
Random rnd = new Random();
byte[] samples = new byte[1024];
rnd.NextBytes(samples);
i++;
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);
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} ");
_udpClient.Send(msg, msg.Length, endpoint);
Console.WriteLine($"Message sent to {_host}:{_port} ");
}
catch (Exception ex)
{
Console.WriteLine($"Error sending message: {ex.Message}");
}
}
catch (Exception ex)

public void StopSending()
{
Console.WriteLine($"Error sending message: {ex.Message}");
_timer?.Dispose();
_timer = null;
}
}

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

public void Dispose()
{
StopSending();
_udpClient.Dispose();
public void Dispose()
{
StopSending();
_udpClient.Dispose();
}
}
}
6 changes: 5 additions & 1 deletion NetSdrClientAppTests/NetSdrClientAppTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
Expand Down
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Лабораторні з реінжинірингу (8×)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=coverage)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=bugs)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient)

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=bugs)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=coverage)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-)

Цей репозиторій використовується для курсу **реінжиніринг ПЗ**.
Мета — провести комплексний реінжиніринг спадкового коду NetSdrClient, включаючи рефакторинг архітектури, покращення якості коду, впровадження сучасних практик розробки та автоматизацію процесів контролю якості через CI/CD пайплайни.
Expand Down