Skip to content
Open
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
21 changes: 21 additions & 0 deletions MyFTP/MyFTP.Test/MyFTP.Test.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="coverlet.collector" Version="3.0.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MyFTPClient\MyFTPClient.csproj" />
<ProjectReference Include="..\MyFTPServer\MyFTPServer.csproj" />
</ItemGroup>

</Project>
91 changes: 91 additions & 0 deletions MyFTP/MyFTP.Test/MyFTPTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
namespace MyFTP.Test;

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MyFTPClient;
using MyFTPServer;
using NUnit.Framework;

public class Tests

This comment was marked as resolved.

This comment was marked as resolved.

{
private Server _server;
private Client _client;
private Stream _fileStream;
private CancellationToken _cancellationToken;

[SetUp]
public void Setup()
{
_server = new Server("127.0.0.1", 80);
_client = new Client("127.0.0.1", 80);
_fileStream = new MemoryStream();
_cancellationToken = new ();
_server.StartServer();
Thread.Sleep(5000);
}

[TearDown]
public void TearDown()
{
_server.StopServer();
}

[Test]
public void GetInvalidFileNameTest()
{
Assert.ThrowsAsync<FileNotFoundException>(() => _client.Get("Text.txt", _fileStream, _cancellationToken));
}

[Test]
public void ListInvalidFileNameTest()
{
Assert.ThrowsAsync<FileNotFoundException>(() => _client.Get("Text.txt", _fileStream, _cancellationToken));
}

[Test]
public async Task ListTest()
{
var data = await _client.List("../../../TestData", _cancellationToken);
Assert.AreEqual("../../../TestData\\Data.txt", data[0].name);
Assert.AreEqual(false, data[0].isDir);
}

[Test]
public async Task GetTest()
{
var destination = "../../../TestData/Data1.txt";
var pathForFile = "../../../TestData/Data.txt";
var result = File.ReadAllBytes(pathForFile);
using (var fstream = new FileStream(destination, FileMode.OpenOrCreate))
{
var data = await _client.Get(pathForFile, fstream, _cancellationToken);
Assert.AreEqual(result.Length, data);
}

var result2 = File.ReadAllBytes(destination);
Assert.AreEqual(result, result2);
File.Delete(destination);
}

[Test]
public void ParallelClientConnection()
{
var clients = new Task[2];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну, два клиента — это не очень убедительно, было бы их хотя бы 200... Но ладно.

for (var i = 0; i < 2; i++)
{
clients[i] = Task.Run(() =>
{
var localClient = new Client("127.0.0.1", 80);
var answer = localClient.List("../../../TestData", _cancellationToken).Result;
Assert.AreEqual("../../../TestData\\Data.txt", answer[0].name);
});
}

foreach (var request in clients)
{
request.Wait();
}
}
}

This comment was marked as resolved.

1 change: 1 addition & 0 deletions MyFTP/MyFTP.Test/TestData/Data.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
qwerty
28 changes: 28 additions & 0 deletions MyFTP/MyFTP.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyFTPClient", "MyFTPClient\MyFTPClient.csproj", "{97AFB503-9655-404C-9CE3-DB6CF51BD205}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyFTP.Test", "MyFTP.Test\MyFTP.Test.csproj", "{D4A4CBB3-3517-431E-8B0D-A71D6389E3B8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyFTPServer", "MyFTPServer\MyFTPServer.csproj", "{D6B47A97-BA0C-4B6C-9A22-3A3BB8AF6F1E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{97AFB503-9655-404C-9CE3-DB6CF51BD205}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97AFB503-9655-404C-9CE3-DB6CF51BD205}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97AFB503-9655-404C-9CE3-DB6CF51BD205}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97AFB503-9655-404C-9CE3-DB6CF51BD205}.Release|Any CPU.Build.0 = Release|Any CPU
{D4A4CBB3-3517-431E-8B0D-A71D6389E3B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4A4CBB3-3517-431E-8B0D-A71D6389E3B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4A4CBB3-3517-431E-8B0D-A71D6389E3B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4A4CBB3-3517-431E-8B0D-A71D6389E3B8}.Release|Any CPU.Build.0 = Release|Any CPU
{D6B47A97-BA0C-4B6C-9A22-3A3BB8AF6F1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6B47A97-BA0C-4B6C-9A22-3A3BB8AF6F1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6B47A97-BA0C-4B6C-9A22-3A3BB8AF6F1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6B47A97-BA0C-4B6C-9A22-3A3BB8AF6F1E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
80 changes: 80 additions & 0 deletions MyFTP/MyFTPClient/Client.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace MyFTPClient;

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// класс клиента для общения с сервером
/// </summary>
public class Client

This comment was marked as resolved.

{
private readonly int _port;
private readonly string _host;

public Client(string host, int port )
{
_host = host;
_port = port;
}

/// <summary>
/// запрос на листинг файлов в папке по пути
/// </summary>
public async Task<(string name, bool isDir)[]> List(string path, CancellationToken cancellationToken)
{
using var client = new TcpClient();
await client.ConnectAsync(_host, _port, cancellationToken);
await using var stream = client.GetStream();
await using var writer = new StreamWriter(stream);
using var reader = new StreamReader(stream);
await writer.WriteLineAsync($"1 {path}");
await writer.FlushAsync();
var info = await reader.ReadLineAsync();
var infoArray = info.Split(' ');
var size = Convert.ToInt32(infoArray[0]);
if (size == -1)
{
throw new FileNotFoundException();
}

var data = new List<(string, bool)>();



for (int i = 1; i < infoArray.Length; i += 2)
Comment on lines +44 to +48
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var data = new List<(string, bool)>();
for (int i = 1; i < infoArray.Length; i += 2)
var data = new List<(string, bool)>();
for (int i = 1; i < infoArray.Length; i += 2)

{

var isDir = Convert.ToBoolean(infoArray[i + 1]);
Comment on lines +49 to +51
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{
var isDir = Convert.ToBoolean(infoArray[i + 1]);
{
var isDir = Convert.ToBoolean(infoArray[i + 1]);

data.Add((infoArray[i], isDir));
}

return data.ToArray();
}

/// <summary>
/// запрос на скачивание нужного файла
/// </summary>
public async Task<long> Get(string path, Stream fileStream, CancellationToken cancellationToken)
{
using var client = new TcpClient();
await client.ConnectAsync(_host, _port, cancellationToken);
await using var stream = client.GetStream();
await using var writer = new StreamWriter(stream);
using var reader = new StreamReader(stream);
await writer.WriteLineAsync($"2 {path}");
await writer.FlushAsync();
var size = Convert.ToInt32(await reader.ReadLineAsync());
if (size == -1)
{
throw new FileNotFoundException();
}

await stream.CopyToAsync(fileStream, cancellationToken);

return size;
}
}
8 changes: 8 additions & 0 deletions MyFTP/MyFTPClient/MyFTPClient.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

</Project>
58 changes: 58 additions & 0 deletions MyFTP/MyFTPClient/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace MyFTPClient;

using System.Threading;
using System;
using System.IO;
using System.Threading.Tasks;

public class Program
{
public static async Task Main(string[] args)
{
var client = new Client(args[0], Convert.ToInt32(args[1]));
var token = new CancellationToken();
Console.WriteLine("1 - List — листинг файлов в директории на сервере\nНапример, 1 ./Test/Files\n");
Console.WriteLine("2 - Get — скачивание файла с сервера\n2 ./Test/Files/file1.txt\n");
Console.WriteLine("Введите !exit, чтобы остановить сервер\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мы клиент, зачем останавливать сервер

Console.WriteLine("Введите команду:");
var request = Console.ReadLine().Split(' ');
while (request[0] != "!exit" || !token.IsCancellationRequested)
{
if (request[0] == "1" && request.Length == 2)
{
try
{
var response = await client.List(request[1], token);
Console.WriteLine(response.Length);
foreach (var file in response)
{
Console.WriteLine($"{file.Item1} {file.Item2}");
}
}
catch (FileNotFoundException)
{
Console.WriteLine("-1");
}
}
else if (request[0] == "2" && request.Length == 2)
{
using var fstream = new FileStream(request[2], FileMode.OpenOrCreate);
try
{
var response = await client.Get(request[1], fstream, token);
Console.WriteLine(response);
}
catch (FileNotFoundException)
{
Console.WriteLine("-1");
}
}
else
{
Console.WriteLine("Некорректная команда!");
}
Console.WriteLine("\nВведите команду:");
request = Console.ReadLine().Split(' ');
}
}
}
8 changes: 8 additions & 0 deletions MyFTP/MyFTPServer/MyFTPServer.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

</Project>
33 changes: 33 additions & 0 deletions MyFTP/MyFTPServer/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace MyFTPServer;

using System;
using System.Threading.Tasks;

public class Program
{
public static async Task Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Вы не передали параметры или передали неверные.");
return;
}
try
{
var server = new Server(args[0], Convert.ToInt32(args[1]));

This comment was marked as resolved.

var serverStop = server.StartServer();
Console.WriteLine("Введите !exit, чтобы остановить сервер");

This comment was marked as resolved.

var command = "";
while (command != "!exit")
{
command = Console.ReadLine();
}

This comment was marked as resolved.

server.StopServer();
await serverStop;
}
catch (ArgumentException)
{
Console.WriteLine("Ошибка!");
}
}
}
Loading