From f57c407e2b7cc51fb326aa12c51be923a780e79e Mon Sep 17 00:00:00 2001 From: Volodya Petrov <71704795+Volodya-Petrov@users.noreply.github.com> Date: Tue, 26 Oct 2021 01:15:22 +0300 Subject: [PATCH 1/7] -added server class, but it doesn't work --- .../.idea/.idea.WorkWithFTP/.idea/.gitignore | 13 ++ .../.idea.WorkWithFTP/.idea/indexLayout.xml | 8 ++ .../.idea/.idea.WorkWithFTP/.idea/vcs.xml | 6 + WorkWithFTP/WorkWithFTP.sln | 16 +++ WorkWithFTP/WorkWithFTP/MyFTP.cs | 120 ++++++++++++++++++ WorkWithFTP/WorkWithFTP/Program.cs | 33 +++++ WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj | 8 ++ 7 files changed, 204 insertions(+) create mode 100644 WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/.gitignore create mode 100644 WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/indexLayout.xml create mode 100644 WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/vcs.xml create mode 100644 WorkWithFTP/WorkWithFTP.sln create mode 100644 WorkWithFTP/WorkWithFTP/MyFTP.cs create mode 100644 WorkWithFTP/WorkWithFTP/Program.cs create mode 100644 WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj diff --git a/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/.gitignore b/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/.gitignore new file mode 100644 index 0000000..495e278 --- /dev/null +++ b/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/.idea.WorkWithFTP.iml +/modules.xml +/contentModel.xml +/projectSettingsUpdater.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/indexLayout.xml b/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/vcs.xml b/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/WorkWithFTP/.idea/.idea.WorkWithFTP/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTP.sln b/WorkWithFTP/WorkWithFTP.sln new file mode 100644 index 0000000..a5f3b6b --- /dev/null +++ b/WorkWithFTP/WorkWithFTP.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkWithFTP", "WorkWithFTP\WorkWithFTP.csproj", "{02771972-984B-42EB-BFB3-3BC98025E7D6}" +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 + EndGlobalSection +EndGlobal diff --git a/WorkWithFTP/WorkWithFTP/MyFTP.cs b/WorkWithFTP/WorkWithFTP/MyFTP.cs new file mode 100644 index 0000000..ed3abf2 --- /dev/null +++ b/WorkWithFTP/WorkWithFTP/MyFTP.cs @@ -0,0 +1,120 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; + +namespace WorkWithFTP +{ + public class MyFTP + { + private readonly int port; + + public MyFTP(int port) + { + this.port = port; + } + + enum Request + { + List = 1, + Get, + Nonsense + } + + public void Run() + { + Task.Run(async () => StartServer()); + } + + private async void StartServer() + { + var listener = new TcpListener(IPAddress.Any, port); + listener.Start(); + while (true) + { + var socket = await listener.AcceptSocketAsync(); + Task.Run(async () => WorkWithClient(socket)); + } + } + + private async void WorkWithClient(Socket socket) + { + var stream = new NetworkStream(socket); + var reader = new StreamReader(stream); + var writer = new StreamWriter(stream); + while (!reader.EndOfStream) + { + var data = await reader.ReadLineAsync(); + (var request, var path) = ParseData(data); + switch (request) + { + case Request.Nonsense: + await writer.WriteAsync("Bro you broke protocol, don't do that anymore, please"); + await writer.FlushAsync(); + break; + case Request.List: + await writer.WriteAsync(ResponseForList(path)); + await writer.FlushAsync(); + break; + default: + var bytes = ResponseForGet(path); + if (bytes == null) + { + await writer.WriteAsync("-1 Файл не существует"); + await writer.FlushAsync(); + break; + } + + await writer.WriteAsync($"{bytes.Length}"); + await writer.FlushAsync(); + stream.Write(bytes); + await stream.FlushAsync(); + break; + } + } + } + + private (Request, string) ParseData(string data) + { + if (data[0] != '1' || data[0] != '2') + { + return (Request.Nonsense, ""); + } + + var request = data[0] == '1' ? Request.List : Request.Get; + if (data[1] != ' ') + { + return (Request.Nonsense, ""); + } + + var path = data.Substring(2); + return (request, path); + } + + private string ResponseForList(string path) + { + if (!Directory.Exists(path)) + { + return "-1 Директории не существует"; + } + var files = Directory.GetFiles(path); + var directories = Directory.GetDirectories(path); + var result = (files.Length + directories.Length).ToString(); + files.ToList().ForEach(x => { result += $" {x} False";}); + directories.ToList().ForEach(x => { result += $" {x} True";}); + return result; + } + + private byte[] ResponseForGet(string path) + { + if (!File.Exists(path)) + { + return null; + } + + return File.ReadAllBytes(path); + } +} +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTP/Program.cs b/WorkWithFTP/WorkWithFTP/Program.cs new file mode 100644 index 0000000..31814cc --- /dev/null +++ b/WorkWithFTP/WorkWithFTP/Program.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace WorkWithFTP +{ + class Program + { + static void Main(string[] args) + { + var server = new MyFTP(8888); + server.Run(); + for (int i = 0; i < 3; i++) + { + var index = i; + Task.Run(async () => + { + var client = new TcpClient("localhost", 8888); + var stream = client.GetStream(); + var streamWriter = new StreamWriter(stream); + var streamReader = new StreamReader(stream); + await streamWriter.WriteAsync("1 ."); + var text = await streamReader.ReadLineAsync(); + Console.WriteLine($"это {index} крутой чувак\n{text}"); + }); + } + Thread.Sleep(100000); + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj b/WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj new file mode 100644 index 0000000..9590466 --- /dev/null +++ b/WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj @@ -0,0 +1,8 @@ + + + + Exe + net5.0 + + + From 02d03b6d963faba671de8c8ff6b8438660222d6f Mon Sep 17 00:00:00 2001 From: Volodya Petrov <71704795+Volodya-Petrov@users.noreply.github.com> Date: Tue, 26 Oct 2021 21:03:49 +0300 Subject: [PATCH 2/7] - fix server - init client proj --- WorkWithFTP/WorkWithFTP.sln | 8 +- WorkWithFTP/WorkWithFTP/MyFTP.cs | 120 ----------------- WorkWithFTP/WorkWithFTP/Program.cs | 33 ----- WorkWithFTP/WorkWithFTPClient/Program.cs | 12 ++ .../WorkWithFTPClient.csproj} | 0 WorkWithFTP/WorkWithFTPServer/Program.cs | 11 ++ WorkWithFTP/WorkWithFTPServer/Server.cs | 126 ++++++++++++++++++ 7 files changed, 156 insertions(+), 154 deletions(-) delete mode 100644 WorkWithFTP/WorkWithFTP/MyFTP.cs delete mode 100644 WorkWithFTP/WorkWithFTP/Program.cs create mode 100644 WorkWithFTP/WorkWithFTPClient/Program.cs rename WorkWithFTP/{WorkWithFTP/WorkWithFTP.csproj => WorkWithFTPClient/WorkWithFTPClient.csproj} (100%) create mode 100644 WorkWithFTP/WorkWithFTPServer/Program.cs create mode 100644 WorkWithFTP/WorkWithFTPServer/Server.cs diff --git a/WorkWithFTP/WorkWithFTP.sln b/WorkWithFTP/WorkWithFTP.sln index a5f3b6b..797b29a 100644 --- a/WorkWithFTP/WorkWithFTP.sln +++ b/WorkWithFTP/WorkWithFTP.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkWithFTP", "WorkWithFTP\WorkWithFTP.csproj", "{02771972-984B-42EB-BFB3-3BC98025E7D6}" +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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -12,5 +14,9 @@ Global {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 EndGlobalSection EndGlobal diff --git a/WorkWithFTP/WorkWithFTP/MyFTP.cs b/WorkWithFTP/WorkWithFTP/MyFTP.cs deleted file mode 100644 index ed3abf2..0000000 --- a/WorkWithFTP/WorkWithFTP/MyFTP.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; - -namespace WorkWithFTP -{ - public class MyFTP - { - private readonly int port; - - public MyFTP(int port) - { - this.port = port; - } - - enum Request - { - List = 1, - Get, - Nonsense - } - - public void Run() - { - Task.Run(async () => StartServer()); - } - - private async void StartServer() - { - var listener = new TcpListener(IPAddress.Any, port); - listener.Start(); - while (true) - { - var socket = await listener.AcceptSocketAsync(); - Task.Run(async () => WorkWithClient(socket)); - } - } - - private async void WorkWithClient(Socket socket) - { - var stream = new NetworkStream(socket); - var reader = new StreamReader(stream); - var writer = new StreamWriter(stream); - while (!reader.EndOfStream) - { - var data = await reader.ReadLineAsync(); - (var request, var path) = ParseData(data); - switch (request) - { - case Request.Nonsense: - await writer.WriteAsync("Bro you broke protocol, don't do that anymore, please"); - await writer.FlushAsync(); - break; - case Request.List: - await writer.WriteAsync(ResponseForList(path)); - await writer.FlushAsync(); - break; - default: - var bytes = ResponseForGet(path); - if (bytes == null) - { - await writer.WriteAsync("-1 Файл не существует"); - await writer.FlushAsync(); - break; - } - - await writer.WriteAsync($"{bytes.Length}"); - await writer.FlushAsync(); - stream.Write(bytes); - await stream.FlushAsync(); - break; - } - } - } - - private (Request, string) ParseData(string data) - { - if (data[0] != '1' || data[0] != '2') - { - return (Request.Nonsense, ""); - } - - var request = data[0] == '1' ? Request.List : Request.Get; - if (data[1] != ' ') - { - return (Request.Nonsense, ""); - } - - var path = data.Substring(2); - return (request, path); - } - - private string ResponseForList(string path) - { - if (!Directory.Exists(path)) - { - return "-1 Директории не существует"; - } - var files = Directory.GetFiles(path); - var directories = Directory.GetDirectories(path); - var result = (files.Length + directories.Length).ToString(); - files.ToList().ForEach(x => { result += $" {x} False";}); - directories.ToList().ForEach(x => { result += $" {x} True";}); - return result; - } - - private byte[] ResponseForGet(string path) - { - if (!File.Exists(path)) - { - return null; - } - - return File.ReadAllBytes(path); - } -} -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTP/Program.cs b/WorkWithFTP/WorkWithFTP/Program.cs deleted file mode 100644 index 31814cc..0000000 --- a/WorkWithFTP/WorkWithFTP/Program.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net.Sockets; -using System.Threading; -using System.Threading.Tasks; - -namespace WorkWithFTP -{ - class Program - { - static void Main(string[] args) - { - var server = new MyFTP(8888); - server.Run(); - for (int i = 0; i < 3; i++) - { - var index = i; - Task.Run(async () => - { - var client = new TcpClient("localhost", 8888); - var stream = client.GetStream(); - var streamWriter = new StreamWriter(stream); - var streamReader = new StreamReader(stream); - await streamWriter.WriteAsync("1 ."); - var text = await streamReader.ReadLineAsync(); - Console.WriteLine($"это {index} крутой чувак\n{text}"); - }); - } - Thread.Sleep(100000); - } - } -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/Program.cs b/WorkWithFTP/WorkWithFTPClient/Program.cs new file mode 100644 index 0000000..3713be8 --- /dev/null +++ b/WorkWithFTP/WorkWithFTPClient/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace WorkWithFTPClient +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj b/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj similarity index 100% rename from WorkWithFTP/WorkWithFTP/WorkWithFTP.csproj rename to WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj diff --git a/WorkWithFTP/WorkWithFTPServer/Program.cs b/WorkWithFTP/WorkWithFTPServer/Program.cs new file mode 100644 index 0000000..f3243ff --- /dev/null +++ b/WorkWithFTP/WorkWithFTPServer/Program.cs @@ -0,0 +1,11 @@ + +namespace WorkWithFTP +{ + class Program + { + static void Main(string[] args) + { + + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPServer/Server.cs b/WorkWithFTP/WorkWithFTPServer/Server.cs new file mode 100644 index 0000000..13c904b --- /dev/null +++ b/WorkWithFTP/WorkWithFTPServer/Server.cs @@ -0,0 +1,126 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace WorkWithFTP +{ + /// + /// Класс сервера, реализующего протокол FTP + /// + public class Server + { + private readonly int port; + private readonly string IPAdress; + private CancellationTokenSource tokenSource; + + public Server(string ipAdress, int port) + { + IPAdress = ipAdress; + this.port = port; + + } + + enum Request + { + List = 1, + Get, + Nonsense + } + + /// + /// Запускает сервер + /// + public async Task StartServer() + { + var listener = new TcpListener(IPAddress.Parse(IPAdress), port); + listener.Start(); + tokenSource = new CancellationTokenSource(); + while (!tokenSource.Token.IsCancellationRequested) + { + var client = await listener.AcceptTcpClientAsync(); + Task.Run(() => WorkWithClient(client)); + } + listener.Stop(); + } + + /// + /// Завершает работу сервера + /// + public void StopServer() => tokenSource.Cancel(); + + private async void WorkWithClient(TcpClient client) + { + using var stream = client.GetStream(); + var reader = new StreamReader(stream); + var writer = new StreamWriter(stream); + var data = await reader.ReadLineAsync(); + (var request, var path) = ParseData(data); + switch (request) + { + case Request.Nonsense: + await writer.WriteAsync("Bro you broke protocol, don't do that anymore, please"); + await writer.FlushAsync(); + break; + case Request.List: + await ResponseForList(path, writer); + break; + default: + await ResponseForGet(path, writer, stream); + break; + } + } + + private (Request, string) ParseData(string data) + { + if (data[0] != '1' && data[0] != '2') + { + return (Request.Nonsense, ""); + } + + var request = data[0] == '1' ? Request.List : Request.Get; + if (data[1] != ' ') + { + return (Request.Nonsense, ""); + } + + var path = data.Substring(2); + return (request, path); + } + + private async Task ResponseForList(string path, StreamWriter writer) + { + if (!Directory.Exists(path)) + { + await writer.WriteLineAsync("-1 Directory doesn't exist"); + await writer.FlushAsync(); + return; + } + var files = Directory.GetFiles(path); + var directories = Directory.GetDirectories(path); + var result = (files.Length + directories.Length).ToString(); + files.ToList().ForEach(x => { result += $" {x} False";}); + directories.ToList().ForEach(x => { result += $" {x} True";}); + await writer.WriteLineAsync(result); + await writer.FlushAsync(); + } + + private async Task ResponseForGet(string path, StreamWriter writer, NetworkStream stream) + { + if (!File.Exists(path)) + { + await writer.WriteLineAsync("-1 File doesn't exist"); + await writer.FlushAsync(); + } + + var fileStream = new FileStream(path, FileMode.Open); + await writer.WriteAsync(fileStream.Length.ToString() + " "); + await writer.FlushAsync(); + await fileStream.CopyToAsync(stream); + await stream.FlushAsync(); + } + } +} \ No newline at end of file From 1d0844724f41af60affefc796f2f970928b34000 Mon Sep 17 00:00:00 2001 From: Volodya Petrov <71704795+Volodya-Petrov@users.noreply.github.com> Date: Tue, 26 Oct 2021 23:01:17 +0300 Subject: [PATCH 3/7] - added client --- WorkWithFTP/WorkWithFTPClient/Client.cs | 69 +++++++++++++++++++ .../WorkWithFTPServer.csproj | 9 +++ 2 files changed, 78 insertions(+) create mode 100644 WorkWithFTP/WorkWithFTPClient/Client.cs create mode 100644 WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj diff --git a/WorkWithFTP/WorkWithFTPClient/Client.cs b/WorkWithFTP/WorkWithFTPClient/Client.cs new file mode 100644 index 0000000..a8f5c78 --- /dev/null +++ b/WorkWithFTP/WorkWithFTPClient/Client.cs @@ -0,0 +1,69 @@ +using System.Dynamic; +using System.IO; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace WorkWithFTPClient +{ + public class Client + { + private readonly int port; + private readonly string hostName; + + public Client(string hostName, int port) + { + this.hostName = hostName; + this.port = port; + } + + public async Task<(long, byte[])> Get(string path) + { + var client = new TcpClient(hostName, port); + using var stream = client.GetStream(); + var writer = new StreamWriter(stream); + var reader = new StreamReader(stream); + await writer.WriteLineAsync($"2 {path}"); + await writer.FlushAsync(); + var size = new char[long.MaxValue.ToString().Length + 1]; + var index = 0; + await reader.ReadAsync(size, index, 1); + while (size[index] != ' ') + { + index++; + await reader.ReadAsync(size, index, 1); + } + + var countInString = size.ToString().Substring(0, size.Length - 1); + var count= long.Parse(countInString); + var bytes = new byte[count]; + for (int i = 0; i < count; i++) + { + await stream.ReadAsync(bytes, i, 1); + } + + return (count, bytes); + } + + public async Task<(string, bool)[]> List(string path) + { + var client = new TcpClient(hostName, port); + using var stream = client.GetStream(); + var writer = new StreamWriter(stream); + var reader = new StreamReader(stream); + await writer.WriteLineAsync($"1 {path}"); + await writer.FlushAsync(); + var response = await reader.ReadLineAsync(); + var splittedResponse = response.Split(' '); + var countOfFiles = int.Parse(splittedResponse[0]); + var files = new (string, bool)[countOfFiles]; + for (int i = 1; i < countOfFiles; i += 2) + { + var isDir = splittedResponse[i + 1] == "True"; + files[(i - 1) / 2] = (splittedResponse[i], isDir); + } + + return files; + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj b/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj new file mode 100644 index 0000000..ed8c327 --- /dev/null +++ b/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + WorkWithFTP + + + From 60be5de1332f87dd5db8c52d80c8091cd2c9f01d Mon Sep 17 00:00:00 2001 From: Volodya Petrov <71704795+Volodya-Petrov@users.noreply.github.com> Date: Wed, 27 Oct 2021 01:17:08 +0300 Subject: [PATCH 4/7] -add comments -add tests --- WorkWithFTP/TestsForFTP/TestsForFTP.csproj | 21 +++++++ WorkWithFTP/TestsForFTP/data/WorkWithVK.dll | Bin 0 -> 8704 bytes WorkWithFTP/TestsForFTP/data/plug.txt | 0 WorkWithFTP/TestsForFTP/tests.cs | 65 ++++++++++++++++++++ WorkWithFTP/WorkWithFTP.sln | 6 ++ WorkWithFTP/WorkWithFTPClient/Client.cs | 32 ++++++++-- WorkWithFTP/WorkWithFTPServer/Server.cs | 1 - 7 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 WorkWithFTP/TestsForFTP/TestsForFTP.csproj create mode 100644 WorkWithFTP/TestsForFTP/data/WorkWithVK.dll create mode 100644 WorkWithFTP/TestsForFTP/data/plug.txt create mode 100644 WorkWithFTP/TestsForFTP/tests.cs diff --git a/WorkWithFTP/TestsForFTP/TestsForFTP.csproj b/WorkWithFTP/TestsForFTP/TestsForFTP.csproj new file mode 100644 index 0000000..4bf7466 --- /dev/null +++ b/WorkWithFTP/TestsForFTP/TestsForFTP.csproj @@ -0,0 +1,21 @@ + + + + net5.0 + + false + + + + + + + + + + + + + + + diff --git a/WorkWithFTP/TestsForFTP/data/WorkWithVK.dll b/WorkWithFTP/TestsForFTP/data/WorkWithVK.dll new file mode 100644 index 0000000000000000000000000000000000000000..6562b1a85372517ac24c03bd2c612b876ea23068 GIT binary patch literal 8704 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 P{TfI6|DpXaXW+j9-n{57 literal 0 HcmV?d00001 diff --git a/WorkWithFTP/TestsForFTP/data/plug.txt b/WorkWithFTP/TestsForFTP/data/plug.txt new file mode 100644 index 0000000..e69de29 diff --git a/WorkWithFTP/TestsForFTP/tests.cs b/WorkWithFTP/TestsForFTP/tests.cs new file mode 100644 index 0000000..669ea8a --- /dev/null +++ b/WorkWithFTP/TestsForFTP/tests.cs @@ -0,0 +1,65 @@ +using System; +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 Client client = new Client("127.0.0.1", 1488); + private Server server = new Server("127.0.0.1", 1488) ; + private string pathForData = "../../../data/"; + + [Test] + public async Task TestShouldThrowExceptionIfListWithIncorrectPath() + { + server.StartServer(); + Assert.Throws(() => client.List("pluuuuug").Wait()); + server.StopServer(); + } + + [Test] + public async Task TestShouldThrowExceptionIfGetWithIncorrectPath() + { + server.StartServer(); + Assert.Throws(() => client.Get("pluuuuug").Wait()); + server.StopServer(); + } + + [Test] + public async Task TestForList() + { + server.StartServer(); + var result = new[] + { + (pathForData + "plug.txt", false), + (pathForData + "WorkWithVK.dll", false), + (pathForData + "kek", true), + (pathForData + "lol", true) + }; + var response = await client.List(pathForData); + server.StopServer(); + 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() + { + server.StartServer(); + var pathForFile = pathForData + "WorkWithVK.dll"; + var result = File.ReadAllBytes(pathForFile); + var response = await client.Get(pathForFile); + server.StopServer(); + Assert.AreEqual(result.Length, response.Item1); + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTP.sln b/WorkWithFTP/WorkWithFTP.sln index 797b29a..3e564d0 100644 --- a/WorkWithFTP/WorkWithFTP.sln +++ b/WorkWithFTP/WorkWithFTP.sln @@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkWithFTPServer", "WorkWi 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 @@ -18,5 +20,9 @@ Global {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 diff --git a/WorkWithFTP/WorkWithFTPClient/Client.cs b/WorkWithFTP/WorkWithFTPClient/Client.cs index a8f5c78..a76b480 100644 --- a/WorkWithFTP/WorkWithFTPClient/Client.cs +++ b/WorkWithFTP/WorkWithFTPClient/Client.cs @@ -1,3 +1,4 @@ +using System; using System.Dynamic; using System.IO; using System.Net.Sockets; @@ -5,7 +6,10 @@ using System.Threading.Tasks; namespace WorkWithFTPClient -{ +{ + /// + /// Клиент сервера + /// public class Client { private readonly int port; @@ -16,7 +20,10 @@ public Client(string hostName, int port) this.hostName = hostName; this.port = port; } - + + /// + /// Скачивает файл с сервера + /// public async Task<(long, byte[])> Get(string path) { var client = new TcpClient(hostName, port); @@ -28,13 +35,21 @@ public Client(string hostName, int port) 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 = size.ToString().Substring(0, size.Length - 1); + var countInString = ""; + for (int i = 0; i < index; i++) + { + countInString += size[i].ToString(); + } var count= long.Parse(countInString); var bytes = new byte[count]; for (int i = 0; i < count; i++) @@ -44,7 +59,10 @@ public Client(string hostName, int port) return (count, bytes); } - + + /// + /// Показывает все папки и файлы, которые лежат на сервере по заданному пути + /// public async Task<(string, bool)[]> List(string path) { var client = new TcpClient(hostName, port); @@ -55,9 +73,13 @@ public Client(string hostName, int port) await writer.FlushAsync(); 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 < countOfFiles; i += 2) + for (int i = 1; i < splittedResponse.Length; i += 2) { var isDir = splittedResponse[i + 1] == "True"; files[(i - 1) / 2] = (splittedResponse[i], isDir); diff --git a/WorkWithFTP/WorkWithFTPServer/Server.cs b/WorkWithFTP/WorkWithFTPServer/Server.cs index 13c904b..1384edd 100644 --- a/WorkWithFTP/WorkWithFTPServer/Server.cs +++ b/WorkWithFTP/WorkWithFTPServer/Server.cs @@ -21,7 +21,6 @@ public Server(string ipAdress, int port) { IPAdress = ipAdress; this.port = port; - } enum Request From 47b53c597b2d1802a6f90030ad829bf6126e7e2e Mon Sep 17 00:00:00 2001 From: Volodya Petrov <89377379140@mail.ru> Date: Mon, 15 Nov 2021 23:34:17 +0300 Subject: [PATCH 5/7] fixes --- WorkWithFTP/TestsForFTP/TestsForFTP.csproj | 6 + WorkWithFTP/TestsForFTP/tests.cs | 65 --------- WorkWithFTP/WorkWithFTPClient/Client.cs | 91 ------------- WorkWithFTP/WorkWithFTPClient/Program.cs | 12 -- .../WorkWithFTPClient.csproj | 9 ++ WorkWithFTP/WorkWithFTPServer/Program.cs | 11 -- WorkWithFTP/WorkWithFTPServer/Server.cs | 125 ------------------ .../WorkWithFTPServer.csproj | 9 ++ 8 files changed, 24 insertions(+), 304 deletions(-) delete mode 100644 WorkWithFTP/TestsForFTP/tests.cs delete mode 100644 WorkWithFTP/WorkWithFTPClient/Client.cs delete mode 100644 WorkWithFTP/WorkWithFTPClient/Program.cs delete mode 100644 WorkWithFTP/WorkWithFTPServer/Program.cs delete mode 100644 WorkWithFTP/WorkWithFTPServer/Server.cs diff --git a/WorkWithFTP/TestsForFTP/TestsForFTP.csproj b/WorkWithFTP/TestsForFTP/TestsForFTP.csproj index 4bf7466..3db82ed 100644 --- a/WorkWithFTP/TestsForFTP/TestsForFTP.csproj +++ b/WorkWithFTP/TestsForFTP/TestsForFTP.csproj @@ -18,4 +18,10 @@ + + + tests.cs + + + diff --git a/WorkWithFTP/TestsForFTP/tests.cs b/WorkWithFTP/TestsForFTP/tests.cs deleted file mode 100644 index 669ea8a..0000000 --- a/WorkWithFTP/TestsForFTP/tests.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -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 Client client = new Client("127.0.0.1", 1488); - private Server server = new Server("127.0.0.1", 1488) ; - private string pathForData = "../../../data/"; - - [Test] - public async Task TestShouldThrowExceptionIfListWithIncorrectPath() - { - server.StartServer(); - Assert.Throws(() => client.List("pluuuuug").Wait()); - server.StopServer(); - } - - [Test] - public async Task TestShouldThrowExceptionIfGetWithIncorrectPath() - { - server.StartServer(); - Assert.Throws(() => client.Get("pluuuuug").Wait()); - server.StopServer(); - } - - [Test] - public async Task TestForList() - { - server.StartServer(); - var result = new[] - { - (pathForData + "plug.txt", false), - (pathForData + "WorkWithVK.dll", false), - (pathForData + "kek", true), - (pathForData + "lol", true) - }; - var response = await client.List(pathForData); - server.StopServer(); - 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() - { - server.StartServer(); - var pathForFile = pathForData + "WorkWithVK.dll"; - var result = File.ReadAllBytes(pathForFile); - var response = await client.Get(pathForFile); - server.StopServer(); - Assert.AreEqual(result.Length, response.Item1); - } - } -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/Client.cs b/WorkWithFTP/WorkWithFTPClient/Client.cs deleted file mode 100644 index a76b480..0000000 --- a/WorkWithFTP/WorkWithFTPClient/Client.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Dynamic; -using System.IO; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace WorkWithFTPClient -{ - /// - /// Клиент сервера - /// - public class Client - { - private readonly int port; - private readonly string hostName; - - public Client(string hostName, int port) - { - this.hostName = hostName; - this.port = port; - } - - /// - /// Скачивает файл с сервера - /// - public async Task<(long, byte[])> Get(string path) - { - var client = new TcpClient(hostName, port); - using var stream = client.GetStream(); - var writer = new StreamWriter(stream); - var reader = new StreamReader(stream); - await writer.WriteLineAsync($"2 {path}"); - await writer.FlushAsync(); - 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); - var bytes = new byte[count]; - for (int i = 0; i < count; i++) - { - await stream.ReadAsync(bytes, i, 1); - } - - return (count, bytes); - } - - /// - /// Показывает все папки и файлы, которые лежат на сервере по заданному пути - /// - public async Task<(string, bool)[]> List(string path) - { - var client = new TcpClient(hostName, port); - using var stream = client.GetStream(); - var writer = new StreamWriter(stream); - var reader = new StreamReader(stream); - await writer.WriteLineAsync($"1 {path}"); - await writer.FlushAsync(); - 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; - } - } -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/Program.cs b/WorkWithFTP/WorkWithFTPClient/Program.cs deleted file mode 100644 index 3713be8..0000000 --- a/WorkWithFTP/WorkWithFTPClient/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace WorkWithFTPClient -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj b/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj index 9590466..65d5abf 100644 --- a/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj +++ b/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj @@ -5,4 +5,13 @@ net5.0 + + + Client.cs + + + Program.cs + + + diff --git a/WorkWithFTP/WorkWithFTPServer/Program.cs b/WorkWithFTP/WorkWithFTPServer/Program.cs deleted file mode 100644 index f3243ff..0000000 --- a/WorkWithFTP/WorkWithFTPServer/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ - -namespace WorkWithFTP -{ - class Program - { - static void Main(string[] args) - { - - } - } -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPServer/Server.cs b/WorkWithFTP/WorkWithFTPServer/Server.cs deleted file mode 100644 index 1384edd..0000000 --- a/WorkWithFTP/WorkWithFTPServer/Server.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Threading; -using System.Threading.Tasks; - -namespace WorkWithFTP -{ - /// - /// Класс сервера, реализующего протокол FTP - /// - public class Server - { - private readonly int port; - private readonly string IPAdress; - private CancellationTokenSource tokenSource; - - public Server(string ipAdress, int port) - { - IPAdress = ipAdress; - this.port = port; - } - - enum Request - { - List = 1, - Get, - Nonsense - } - - /// - /// Запускает сервер - /// - public async Task StartServer() - { - var listener = new TcpListener(IPAddress.Parse(IPAdress), port); - listener.Start(); - tokenSource = new CancellationTokenSource(); - while (!tokenSource.Token.IsCancellationRequested) - { - var client = await listener.AcceptTcpClientAsync(); - Task.Run(() => WorkWithClient(client)); - } - listener.Stop(); - } - - /// - /// Завершает работу сервера - /// - public void StopServer() => tokenSource.Cancel(); - - private async void WorkWithClient(TcpClient client) - { - using var stream = client.GetStream(); - var reader = new StreamReader(stream); - var writer = new StreamWriter(stream); - var data = await reader.ReadLineAsync(); - (var request, var path) = ParseData(data); - switch (request) - { - case Request.Nonsense: - await writer.WriteAsync("Bro you broke protocol, don't do that anymore, please"); - await writer.FlushAsync(); - break; - case Request.List: - await ResponseForList(path, writer); - break; - default: - await ResponseForGet(path, writer, stream); - break; - } - } - - private (Request, string) ParseData(string data) - { - if (data[0] != '1' && data[0] != '2') - { - return (Request.Nonsense, ""); - } - - var request = data[0] == '1' ? Request.List : Request.Get; - if (data[1] != ' ') - { - return (Request.Nonsense, ""); - } - - var path = data.Substring(2); - return (request, path); - } - - private async Task ResponseForList(string path, StreamWriter writer) - { - if (!Directory.Exists(path)) - { - await writer.WriteLineAsync("-1 Directory doesn't exist"); - await writer.FlushAsync(); - return; - } - var files = Directory.GetFiles(path); - var directories = Directory.GetDirectories(path); - var result = (files.Length + directories.Length).ToString(); - files.ToList().ForEach(x => { result += $" {x} False";}); - directories.ToList().ForEach(x => { result += $" {x} True";}); - await writer.WriteLineAsync(result); - await writer.FlushAsync(); - } - - private async Task ResponseForGet(string path, StreamWriter writer, NetworkStream stream) - { - if (!File.Exists(path)) - { - await writer.WriteLineAsync("-1 File doesn't exist"); - await writer.FlushAsync(); - } - - var fileStream = new FileStream(path, FileMode.Open); - await writer.WriteAsync(fileStream.Length.ToString() + " "); - await writer.FlushAsync(); - await fileStream.CopyToAsync(stream); - await stream.FlushAsync(); - } - } -} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj b/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj index ed8c327..544b24d 100644 --- a/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj +++ b/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj @@ -6,4 +6,13 @@ WorkWithFTP + + + Program.cs + + + Server.cs + + + From 8b11a715b1821872c63fb58eff086358a065fa37 Mon Sep 17 00:00:00 2001 From: Volodya Petrov <89377379140@mail.ru> Date: Mon, 15 Nov 2021 23:40:02 +0300 Subject: [PATCH 6/7] added files --- WorkWithFTP/TestsForFTP/TestsForFTP.csproj | 6 - WorkWithFTP/TestsForFTP/tests.cs | 77 +++++++++ WorkWithFTP/WorkWithFTPClient/Client.cs | 92 +++++++++++ WorkWithFTP/WorkWithFTPClient/Program.cs | 57 +++++++ .../WorkWithFTPClient.csproj | 9 - WorkWithFTP/WorkWithFTPServer/Program.cs | 31 ++++ WorkWithFTP/WorkWithFTPServer/Server.cs | 155 ++++++++++++++++++ .../WorkWithFTPServer.csproj | 9 - 8 files changed, 412 insertions(+), 24 deletions(-) create mode 100644 WorkWithFTP/TestsForFTP/tests.cs create mode 100644 WorkWithFTP/WorkWithFTPClient/Client.cs create mode 100644 WorkWithFTP/WorkWithFTPClient/Program.cs create mode 100644 WorkWithFTP/WorkWithFTPServer/Program.cs create mode 100644 WorkWithFTP/WorkWithFTPServer/Server.cs diff --git a/WorkWithFTP/TestsForFTP/TestsForFTP.csproj b/WorkWithFTP/TestsForFTP/TestsForFTP.csproj index 3db82ed..4bf7466 100644 --- a/WorkWithFTP/TestsForFTP/TestsForFTP.csproj +++ b/WorkWithFTP/TestsForFTP/TestsForFTP.csproj @@ -18,10 +18,4 @@ - - - tests.cs - - - diff --git a/WorkWithFTP/TestsForFTP/tests.cs b/WorkWithFTP/TestsForFTP/tests.cs new file mode 100644 index 0000000..46155af --- /dev/null +++ b/WorkWithFTP/TestsForFTP/tests.cs @@ -0,0 +1,77 @@ +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/"; + + [SetUp] + public void SetUp() + { + server = new Server(ip, port); + client = new Client(ip, port); + } + + [Test] + public async Task TestShouldThrowExceptionIfListWithIncorrectPath() + { + using var handle = server.StartServer(); + Assert.Throws(() => client.List("pluuuuug").Wait()); + } + + [Test] + public async Task TestShouldThrowExceptionIfGetWithIncorrectPath() + { + using var handle = server.StartServer(); + Assert.Throws(() => client.Get("pluuuuug", null).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); + 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); + Assert.AreEqual(result.Length, response); + } + + var result2 = File.ReadAllBytes(destination); + Assert.AreEqual(result, result2); + File.Delete(destination); + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/Client.cs b/WorkWithFTP/WorkWithFTPClient/Client.cs new file mode 100644 index 0000000..e7a2151 --- /dev/null +++ b/WorkWithFTP/WorkWithFTPClient/Client.cs @@ -0,0 +1,92 @@ +using System; +using System.Dynamic; +using System.IO; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace WorkWithFTPClient +{ + /// + /// Клиент сервера + /// + public class Client + { + private readonly int port; + private readonly string hostName; + + public Client(string hostName, int port) + { + this.hostName = hostName; + this.port = port; + } + + /// + /// Скачивает файл с сервера + /// + public async Task Get(string path, FileStream destination) + { + using var client = new TcpClient(); + await client.ConnectAsync(hostName, port); + 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); + var readByte = new byte[2]; + for (int i = 0; i < count; i++) + { + await stream.ReadAsync(readByte, 0, 1); + await destination.WriteAsync(readByte, 0, 1); + } + + return count; + } + + /// + /// Показывает все папки и файлы, которые лежат на сервере по заданному пути + /// + public async Task<(string, bool)[]> List(string path) + { + using var client = new TcpClient(); + await client.ConnectAsync(hostName, port); + 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; + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/Program.cs b/WorkWithFTP/WorkWithFTPClient/Program.cs new file mode 100644 index 0000000..ab66d9c --- /dev/null +++ b/WorkWithFTP/WorkWithFTPClient/Program.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; +using System.Threading.Tasks; + +namespace WorkWithFTPClient +{ + class Program + { + static async Task Main(string[] args) + { + Console.WriteLine("Введите IP адресс сервера:"); + var ip = Console.ReadLine(); + Console.WriteLine("Введите, к какому порту обращаться:"); + int.TryParse(Console.ReadLine(), out var port); + var client = new Client(ip, port); + Console.WriteLine("List:\nФормат запроса:1 \npath - путь к директории относительно того места, где запущен сервер"); + Console.WriteLine("Get:\nФормат запроса:2 \npath1 - путь к файлу относительно того места, где запущен сервер\n" + + "npath2 - путь к файлу на локальной машине, где запущен клиент"); + Console.WriteLine("Введите exit, если хотите закрыть соединение с сервером"); + var request = Console.ReadLine().Split(' '); + while (request[0] != "exit") + { + if (request[0] == "1") + { + try + { + var response = await client.List(request[1]); + 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 response = client.Get(request[1], fstream); + } + catch (Exception e) + { + Console.WriteLine("Упс... Что-то пошло не так"); + } + } + } + request = Console.ReadLine().Split(' '); + } + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj b/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj index 65d5abf..9590466 100644 --- a/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj +++ b/WorkWithFTP/WorkWithFTPClient/WorkWithFTPClient.csproj @@ -5,13 +5,4 @@ net5.0 - - - Client.cs - - - Program.cs - - - diff --git a/WorkWithFTP/WorkWithFTPServer/Program.cs b/WorkWithFTP/WorkWithFTPServer/Program.cs new file mode 100644 index 0000000..5a75de6 --- /dev/null +++ b/WorkWithFTP/WorkWithFTPServer/Program.cs @@ -0,0 +1,31 @@ + +using System; + +namespace WorkWithFTP +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Введите ip, на котором будет запущен сервер:"); + var ip = Console.ReadLine(); + Console.WriteLine("Введите порт сервера:"); + var port = int.Parse(Console.ReadLine()); + 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("Упс... что-то пошло не так"); + } + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPServer/Server.cs b/WorkWithFTP/WorkWithFTPServer/Server.cs new file mode 100644 index 0000000..f08cbc3 --- /dev/null +++ b/WorkWithFTP/WorkWithFTPServer/Server.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace WorkWithFTP +{ + /// + /// Класс сервера, реализующего протокол FTP + /// + public class Server + { + private readonly int port; + private readonly string IPAdress; + private CancellationTokenSource tokenSource; + private List tasks; + private TcpListener listener; + + private class ServerHandler : IDisposable + { + private Action stopServer; + + public ServerHandler(Action stopServer) + { + this.stopServer = stopServer; + } + + public void Dispose() + { + stopServer(); + } + } + + public Server(string ipAdress, int port) + { + IPAdress = ipAdress; + this.port = port; + tasks = new(); + } + + enum Request + { + List = 1, + Get, + Nonsense + } + + /// + /// Запускает сервер + /// + public IDisposable StartServer() + { + listener = new TcpListener(IPAddress.Parse(IPAdress), port); + listener.Start(); + tokenSource = new CancellationTokenSource(); + var mainTask = Task.Run(async () => + { + while (!tokenSource.Token.IsCancellationRequested) + { + var client = await listener.AcceptTcpClientAsync(); + var task = Task.Run(() => WorkWithClient(client)); + tasks.Add(task); + } + }); + tasks.Add(mainTask); + return new ServerHandler(StopServer); + } + + /// + /// Завершает работу сервера + /// + public void StopServer() + { + tokenSource.Cancel(); + Task.WhenAll(tasks); + listener.Stop(); + } + + private async void WorkWithClient(TcpClient client) + { + using (client) + { + using var stream = client.GetStream(); + using var reader = new StreamReader(stream); + using var writer = new StreamWriter(stream) {AutoFlush = true}; + var data = await reader.ReadLineAsync(); + (var request, var path) = ParseData(data); + switch (request) + { + case Request.Nonsense: + await writer.WriteAsync("Bro you broke protocol, don't do that anymore, please"); + break; + case Request.List: + await ResponseForList(path, writer); + break; + default: + await ResponseForGet(path, writer, stream); + break; + } + } + } + + private (Request, string) ParseData(string data) + { + if (data[0] != '1' && data[0] != '2') + { + return (Request.Nonsense, ""); + } + + var request = data[0] == '1' ? Request.List : Request.Get; + if (data[1] != ' ') + { + return (Request.Nonsense, ""); + } + + var path = data.Substring(2); + return (request, path); + } + + private async Task ResponseForList(string path, StreamWriter writer) + { + if (!Directory.Exists(path)) + { + await writer.WriteLineAsync("-1 Directory doesn't exist"); + return; + } + var files = Directory.GetFiles(path); + var directories = Directory.GetDirectories(path); + var response = new StringBuilder(); + response.Append((files.Length + directories.Length).ToString()); + files.ToList().ForEach(x => response.Append($" {x} False")); + directories.ToList().ForEach(x => response.Append($" {x} True")); + await writer.WriteLineAsync(response.ToString()); + } + + private async Task ResponseForGet(string path, StreamWriter writer, NetworkStream stream) + { + if (!File.Exists(path)) + { + await writer.WriteLineAsync("-1 File doesn't exist"); + return; + } + + using var fileStream = new FileStream(path, FileMode.Open); + await writer.WriteAsync(fileStream.Length.ToString() + " "); + await fileStream.CopyToAsync(stream); + await stream.FlushAsync(); + } + } +} \ No newline at end of file diff --git a/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj b/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj index 544b24d..ed8c327 100644 --- a/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj +++ b/WorkWithFTP/WorkWithFTPServer/WorkWithFTPServer.csproj @@ -6,13 +6,4 @@ WorkWithFTP - - - Program.cs - - - Server.cs - - - From 81dede3bc4df344d10fee64d9b691643448ceb4c Mon Sep 17 00:00:00 2001 From: Volodya Petrov <89377379140@mail.ru> Date: Mon, 6 Dec 2021 19:30:33 +0300 Subject: [PATCH 7/7] fixes --- WorkWithFTP/TestsForFTP/{tests.cs => Tests.cs} | 10 ++++++---- WorkWithFTP/WorkWithFTPClient/Client.cs | 17 ++++++----------- WorkWithFTP/WorkWithFTPClient/Program.cs | 13 ++++++------- WorkWithFTP/WorkWithFTPServer/Program.cs | 8 +++----- 4 files changed, 21 insertions(+), 27 deletions(-) rename WorkWithFTP/TestsForFTP/{tests.cs => Tests.cs} (88%) diff --git a/WorkWithFTP/TestsForFTP/tests.cs b/WorkWithFTP/TestsForFTP/Tests.cs similarity index 88% rename from WorkWithFTP/TestsForFTP/tests.cs rename to WorkWithFTP/TestsForFTP/Tests.cs index 46155af..44079ac 100644 --- a/WorkWithFTP/TestsForFTP/tests.cs +++ b/WorkWithFTP/TestsForFTP/Tests.cs @@ -17,26 +17,28 @@ public class Tests 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(() => client.List("pluuuuug").Wait()); + Assert.Throws(() => client.List("pluuuuug", tokenSource.Token).Wait()); } [Test] public async Task TestShouldThrowExceptionIfGetWithIncorrectPath() { using var handle = server.StartServer(); - Assert.Throws(() => client.Get("pluuuuug", null).Wait()); + Assert.Throws(() => client.Get("pluuuuug", null, tokenSource.Token).Wait()); } [Test] @@ -48,7 +50,7 @@ public async Task TestForList() (pathForData + "plug.txt", false), (pathForData + "WorkWithVK.dll", false), }; - var response = await client.List(pathForData); + var response = await client.List(pathForData, tokenSource.Token); Assert.AreEqual(result.Length, response.Length); for (int i = 0; i < result.Length; i++) { @@ -65,7 +67,7 @@ public async Task TestForGet() var result = File.ReadAllBytes(pathForFile); using (var fstream = new FileStream(destination, FileMode.OpenOrCreate)) { - var response = await client.Get(pathForFile, fstream); + var response = await client.Get(pathForFile, fstream, tokenSource.Token); Assert.AreEqual(result.Length, response); } diff --git a/WorkWithFTP/WorkWithFTPClient/Client.cs b/WorkWithFTP/WorkWithFTPClient/Client.cs index e7a2151..352e4fc 100644 --- a/WorkWithFTP/WorkWithFTPClient/Client.cs +++ b/WorkWithFTP/WorkWithFTPClient/Client.cs @@ -3,6 +3,7 @@ using System.IO; using System.Net.Sockets; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace WorkWithFTPClient @@ -24,10 +25,10 @@ public Client(string hostName, int port) /// /// Скачивает файл с сервера /// - public async Task Get(string path, FileStream destination) + public async Task Get(string path, FileStream destination, CancellationToken token) { using var client = new TcpClient(); - await client.ConnectAsync(hostName, port); + 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); @@ -51,23 +52,17 @@ public async Task Get(string path, FileStream destination) countInString += size[i].ToString(); } var count = long.Parse(countInString); - var readByte = new byte[2]; - for (int i = 0; i < count; i++) - { - await stream.ReadAsync(readByte, 0, 1); - await destination.WriteAsync(readByte, 0, 1); - } - + await stream.CopyToAsync(destination, token); return count; } /// /// Показывает все папки и файлы, которые лежат на сервере по заданному пути /// - public async Task<(string, bool)[]> List(string path) + public async Task<(string, bool)[]> List(string path, CancellationToken token) { using var client = new TcpClient(); - await client.ConnectAsync(hostName, port); + 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); diff --git a/WorkWithFTP/WorkWithFTPClient/Program.cs b/WorkWithFTP/WorkWithFTPClient/Program.cs index ab66d9c..f4a7030 100644 --- a/WorkWithFTP/WorkWithFTPClient/Program.cs +++ b/WorkWithFTP/WorkWithFTPClient/Program.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading; using System.Threading.Tasks; namespace WorkWithFTPClient @@ -8,11 +9,7 @@ class Program { static async Task Main(string[] args) { - Console.WriteLine("Введите IP адресс сервера:"); - var ip = Console.ReadLine(); - Console.WriteLine("Введите, к какому порту обращаться:"); - int.TryParse(Console.ReadLine(), out var port); - var client = new Client(ip, port); + var client = new Client(args[0], int.Parse(args[1])); Console.WriteLine("List:\nФормат запроса:1 \npath - путь к директории относительно того места, где запущен сервер"); Console.WriteLine("Get:\nФормат запроса:2 \npath1 - путь к файлу относительно того места, где запущен сервер\n" + "npath2 - путь к файлу на локальной машине, где запущен клиент"); @@ -24,7 +21,8 @@ static async Task Main(string[] args) { try { - var response = await client.List(request[1]); + var sourceToken = new CancellationTokenSource(); + var response = await client.List(request[1], sourceToken.Token); foreach (var file in response) { Console.WriteLine($"{file.Item1} {file.Item2}"); @@ -42,7 +40,8 @@ static async Task Main(string[] args) { try { - var response = client.Get(request[1], fstream); + var sourceToken = new CancellationTokenSource(); + var response = client.Get(request[1], fstream, sourceToken.Token); } catch (Exception e) { diff --git a/WorkWithFTP/WorkWithFTPServer/Program.cs b/WorkWithFTP/WorkWithFTPServer/Program.cs index 5a75de6..0bdeaa0 100644 --- a/WorkWithFTP/WorkWithFTPServer/Program.cs +++ b/WorkWithFTP/WorkWithFTPServer/Program.cs @@ -6,11 +6,9 @@ namespace WorkWithFTP class Program { static void Main(string[] args) - { - Console.WriteLine("Введите ip, на котором будет запущен сервер:"); - var ip = Console.ReadLine(); - Console.WriteLine("Введите порт сервера:"); - var port = int.Parse(Console.ReadLine()); + { + string ip = args[0]; + var port = int.Parse(args[1]); try { var server = new Server(ip, port);