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
13 changes: 13 additions & 0 deletions WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 79 additions & 0 deletions WorkWithFTP/TestsForFTP/Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using WorkWithFTPClient;
using WorkWithFTP;
using NUnit.Framework;

namespace TestsForFTP
{
public class Tests
{
private string ip = "127.0.0.1";
private int port = 1488;
private Client client;
private Server server;
private string pathForData = "../../../data/";
private CancellationTokenSource tokenSource;

[SetUp]
public void SetUp()
{
server = new Server(ip, port);
client = new Client(ip, port);
tokenSource = new CancellationTokenSource();
}

[Test]
public async Task TestShouldThrowExceptionIfListWithIncorrectPath()
{
using var handle = server.StartServer();
Assert.Throws<AggregateException>(() => client.List("pluuuuug", tokenSource.Token).Wait());
Copy link
Contributor

Choose a reason for hiding this comment

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

Если Вы не собираетесь отменяться по этому tokenSource-у, то передавайте просто CancellationToken.None

}

[Test]
public async Task TestShouldThrowExceptionIfGetWithIncorrectPath()
{
using var handle = server.StartServer();
Assert.Throws<AggregateException>(() => client.Get("pluuuuug", null, tokenSource.Token).Wait());
}

[Test]
public async Task TestForList()
{
using var handle = server.StartServer();
var result = new[]
{
(pathForData + "plug.txt", false),
(pathForData + "WorkWithVK.dll", false),
};
var response = await client.List(pathForData, tokenSource.Token);
Assert.AreEqual(result.Length, response.Length);
for (int i = 0; i < result.Length; i++)
{
Assert.IsTrue(response.Any(x => x == result[i]));
}
}

[Test]
public async Task TestForGet()
{
using var handle = server.StartServer();
var destination = pathForData + "WorkWithVK2.dll";
var pathForFile = pathForData + "WorkWithVK.dll";
var result = File.ReadAllBytes(pathForFile);
using (var fstream = new FileStream(destination, FileMode.OpenOrCreate))
{
var response = await client.Get(pathForFile, fstream, tokenSource.Token);
Assert.AreEqual(result.Length, response);
}

var result2 = File.ReadAllBytes(destination);
Assert.AreEqual(result, result2);
File.Delete(destination);
}
}
}
21 changes: 21 additions & 0 deletions WorkWithFTP/TestsForFTP/TestsForFTP.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>

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

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<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="..\WorkWithFTPClient\WorkWithFTPClient.csproj" />
<ProjectReference Include="..\WorkWithFTPServer\WorkWithFTPServer.csproj" />
</ItemGroup>

</Project>
Binary file added WorkWithFTP/TestsForFTP/data/WorkWithVK.dll
Binary file not shown.
Empty file.
28 changes: 28 additions & 0 deletions WorkWithFTP/WorkWithFTP.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}") = "WorkWithFTPServer", "WorkWithFTPServer\WorkWithFTPServer.csproj", "{02771972-984B-42EB-BFB3-3BC98025E7D6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkWithFTPClient", "WorkWithFTPClient\WorkWithFTPClient.csproj", "{23186ECF-69E7-457E-A474-5568A6549E80}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsForFTP", "TestsForFTP\TestsForFTP.csproj", "{3DF979A8-9F50-45B9-8F41-A84270CDCA17}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{02771972-984B-42EB-BFB3-3BC98025E7D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02771972-984B-42EB-BFB3-3BC98025E7D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02771972-984B-42EB-BFB3-3BC98025E7D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02771972-984B-42EB-BFB3-3BC98025E7D6}.Release|Any CPU.Build.0 = Release|Any CPU
{23186ECF-69E7-457E-A474-5568A6549E80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23186ECF-69E7-457E-A474-5568A6549E80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23186ECF-69E7-457E-A474-5568A6549E80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23186ECF-69E7-457E-A474-5568A6549E80}.Release|Any CPU.Build.0 = Release|Any CPU
{3DF979A8-9F50-45B9-8F41-A84270CDCA17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DF979A8-9F50-45B9-8F41-A84270CDCA17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DF979A8-9F50-45B9-8F41-A84270CDCA17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DF979A8-9F50-45B9-8F41-A84270CDCA17}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
87 changes: 87 additions & 0 deletions WorkWithFTP/WorkWithFTPClient/Client.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Dynamic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WorkWithFTPClient
{
/// <summary>
/// Клиент сервера
/// </summary>
public class Client
{
private readonly int port;
private readonly string hostName;

public Client(string hostName, int port)
{
this.hostName = hostName;
this.port = port;
}

/// <summary>
/// Скачивает файл с сервера
/// </summary>
public async Task<long> Get(string path, FileStream destination, CancellationToken token)
{
using var client = new TcpClient();
await client.ConnectAsync(hostName, port, token);
using var stream = client.GetStream();
using var writer = new StreamWriter(stream){AutoFlush = true};
using var reader = new StreamReader(stream);
await writer.WriteLineAsync($"2 {path}");
var size = new char[long.MaxValue.ToString().Length + 1];
var index = 0;
await reader.ReadAsync(size, index, 1);
if (size[0] == '-')
{
throw new ArgumentException();
}
while (size[index] != ' ')
{
index++;
await reader.ReadAsync(size, index, 1);
}

var countInString = "";
for (int i = 0; i < index; i++)
{
countInString += size[i].ToString();
}
var count = long.Parse(countInString);
await stream.CopyToAsync(destination, token);
return count;
}

/// <summary>
/// Показывает все папки и файлы, которые лежат на сервере по заданному пути
/// </summary>
public async Task<(string, bool)[]> List(string path, CancellationToken token)
{
using var client = new TcpClient();
await client.ConnectAsync(hostName, port, token);
using var stream = client.GetStream();
using var writer = new StreamWriter(stream){AutoFlush = true};
using var reader = new StreamReader(stream);
await writer.WriteLineAsync($"1 {path}");
var response = await reader.ReadLineAsync();
var splittedResponse = response.Split(' ');
if (splittedResponse[0] == "-1")
{
throw new ArgumentException();
}
var countOfFiles = int.Parse(splittedResponse[0]);
var files = new (string, bool)[countOfFiles];
for (int i = 1; i < splittedResponse.Length; i += 2)
{
var isDir = splittedResponse[i + 1] == "True";
files[(i - 1) / 2] = (splittedResponse[i], isDir);
}

return files;
}
}
}
56 changes: 56 additions & 0 deletions WorkWithFTP/WorkWithFTPClient/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace WorkWithFTPClient
{
class Program
{
static async Task Main(string[] args)
{
var client = new Client(args[0], int.Parse(args[1]));
Copy link
Contributor

Choose a reason for hiding this comment

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

Надо проверить, что они действительно были переданы, и если нет, вывести справку об использовании

Console.WriteLine("List:\nФормат запроса:1 <path: String>\npath - путь к директории относительно того места, где запущен сервер");
Console.WriteLine("Get:\nФормат запроса:2 <path1: String> <path2: String>\npath1 - путь к файлу относительно того места, где запущен сервер\n" +
"npath2 - путь к файлу на локальной машине, где запущен клиент");
Console.WriteLine("Введите exit, если хотите закрыть соединение с сервером");
var request = Console.ReadLine().Split(' ');
Copy link
Contributor

Choose a reason for hiding this comment

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

Это полумеры :) Ещё раз, хочу команду вида dotnet run -- 127.0.0.1 8888 --list .

while (request[0] != "exit")
{
if (request[0] == "1")
{
try
{
var sourceToken = new CancellationTokenSource();
var response = await client.List(request[1], sourceToken.Token);
foreach (var file in response)
{
Console.WriteLine($"{file.Item1} {file.Item2}");
}
}
catch (Exception e)
{
Console.WriteLine("Упс... Что-то пошло не так");
}
}

if (request[0] == "2")
{
using (var fstream = new FileStream(request[2], FileMode.OpenOrCreate))
{
try
{
var sourceToken = new CancellationTokenSource();
var response = client.Get(request[1], fstream, sourceToken.Token);
}
catch (Exception e)
{
Console.WriteLine("Упс... Что-то пошло не так");
}
}
}
request = Console.ReadLine().Split(' ');
}
}
}
}
8 changes: 8 additions & 0 deletions WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.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>net5.0</TargetFramework>
Copy link
Contributor

Choose a reason for hiding this comment

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

Можно уже на .net 6 и C# 10 переходить, там всякие крутые штуки типа file-scoped namespaces и глобальных юзингов.

</PropertyGroup>

</Project>
29 changes: 29 additions & 0 deletions WorkWithFTP/WorkWithFTPServer/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

using System;

namespace WorkWithFTP
{
class Program
{
static void Main(string[] args)
{
string ip = args[0];
var port = int.Parse(args[1]);
try
{
var server = new Server(ip, port);
using var handler = server.StartServer();
Console.WriteLine("Введите stop, чтобы остановить сервер");
var command = "";
while (command != "stop")
{
command = Console.ReadLine();
}
}
catch (Exception e)
{
Console.WriteLine("Упс... что-то пошло не так");
}
}
}
}
Loading