From 5368267934a11716944090a12f9efaf0a4f166b0 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Fri, 22 Oct 2021 21:51:24 +0300 Subject: [PATCH 01/17] add service --- MyFTP/MyFTP/Client.cs | 29 ++++++++++++++ MyFTP/MyFTP/Server.cs | 93 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 MyFTP/MyFTP/Client.cs create mode 100644 MyFTP/MyFTP/Server.cs diff --git a/MyFTP/MyFTP/Client.cs b/MyFTP/MyFTP/Client.cs new file mode 100644 index 0000000..a6ce151 --- /dev/null +++ b/MyFTP/MyFTP/Client.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Threading.Tasks; + +namespace MyFTP +{ + public class Client + { + private int _port; + private string _host; + + Client(int port, string host) + { + _port = port; + _host = host; + } + + public async Task List(string path, Stream stream) + { + + } + + public async Task Get(string path, Stream stream) + { + + } + } +} diff --git a/MyFTP/MyFTP/Server.cs b/MyFTP/MyFTP/Server.cs new file mode 100644 index 0000000..2b8f233 --- /dev/null +++ b/MyFTP/MyFTP/Server.cs @@ -0,0 +1,93 @@ +using System; +using System.Data; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace MyFTP +{ + public class Server + { + private int _port; + private readonly TcpListener _listener; + private CancellationTokenSource _cancellationToken; + + Server(int port, string host, CancellationTokenSource cancellationToken) + { + _port = port; + _listener = new TcpListener(IPAddress.Parse(host), port); + } + + public async Task StartServer() + { + _listener.Start(); + while (_cancellationToken.IsCancellationRequested) + { + var client = await _listener.AcceptTcpClientAsync(); + await Task.Run(() => Working(client)); + } + } + + public void StopServer() + => _cancellationToken.Cancel(); + + public async Task Working(TcpClient client) + { + var stream = client.GetStream(); + var reader = new StreamReader(stream); + var writer = new StreamWriter(stream); + var request = await reader.ReadLineAsync(); + var (command, path) = (request?.Split()[0], request?.Split()[1]); + switch (command) + { + case "1": + await List(writer, path); + break; + case "2": + await Get(writer, path); + break; + default: + throw new ArgumentException(); + } + } + + public async Task List(StreamWriter writer,string path) + { + if (!Directory.Exists(path)) + { + await writer.WriteLineAsync("-1"); + return; + } + + var files = Directory.GetFiles(path); + var directories = Directory.GetDirectories(path); + var size = files.Length + directories.Length; + await writer.WriteAsync("{size}"); + + foreach (var file in files) + { + await writer.WriteAsync($" {file} false"); + } + + foreach (var directory in directories) + { + await writer.WriteAsync($" {directory} true"); + } + } + + public async Task Get(StreamWriter writer,string path) + { + if (!File.Exists(path)) + { + await writer.WriteLineAsync("-1"); + return; + } + + var size = new FileInfo(path).Length; + await writer.WriteAsync($"{size}"); + /// write file + } + } +} \ No newline at end of file From db8e1521aa40f809a8e54ca8a542121ae103fa2c Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Wed, 27 Oct 2021 02:27:07 +0300 Subject: [PATCH 02/17] add client and test --- MyFTP/ConsoleApp1/Client.cs | 64 ++++++++++++++++++++++++++++ MyFTP/MyFTP.Test/TestData/Data.txt | 1 + MyFTP/MyFTP.Test/TestData/File.txt | 1 + MyFTP/MyFTP/Client.cs | 68 +++++++++++++++++++++++++----- MyFTP/MyFTP/Program.cs | 18 ++++++++ MyFTP/MyFTP/Server.cs | 62 +++++++++++++++++---------- 6 files changed, 182 insertions(+), 32 deletions(-) create mode 100644 MyFTP/ConsoleApp1/Client.cs create mode 100644 MyFTP/MyFTP.Test/TestData/Data.txt create mode 100644 MyFTP/MyFTP.Test/TestData/File.txt create mode 100644 MyFTP/MyFTP/Program.cs diff --git a/MyFTP/ConsoleApp1/Client.cs b/MyFTP/ConsoleApp1/Client.cs new file mode 100644 index 0000000..b1c3dc2 --- /dev/null +++ b/MyFTP/ConsoleApp1/Client.cs @@ -0,0 +1,64 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Threading.Tasks; + +namespace ConsoleApp1 +{ + public class Client + { + private readonly int _port; + private readonly string _host; + + public Client(int port, string host) + { + _port = port; + _host = host; + } + + public async Task<(string name, bool isDir)[]> List(string path) + { + using var client = new TcpClient(_host, _port); + await using var stream = client.GetStream(); + var writer = new StreamWriter(stream) {AutoFlush = true}; + await writer.WriteLineAsync($"1 {path}"); + var reader = new StreamReader(stream); + var size = Convert.ToInt32(await reader.ReadLineAsync()); + + if (size == -1) + { + return null; + } + + var data = new (string name, bool isDir)[size]; + + for (int i = 0; i < size; i++) + { + var name = await reader.ReadLineAsync(); + var isDir = Convert.ToBoolean(await reader.ReadLineAsync()); + data[i] = (name, isDir); + } + + return data; + } + + public async Task Get(string path, Stream fileStream) + { + var client = new TcpClient(_host, _port); + await using var stream = client.GetStream(); + var writer = new StreamWriter(stream) {AutoFlush = true}; + await writer.WriteLineAsync($"2 {path}"); + var reader = new StreamReader(stream); + var size = Convert.ToInt32(await reader.ReadLineAsync()); + if (size == -1) + { + throw new FileNotFoundException(); + } + + var content = new byte[size]; + await reader.BaseStream.ReadAsync(content, 0, size); + await stream.CopyToAsync(fileStream); + fileStream.Position = 0; + } + } +} \ No newline at end of file diff --git a/MyFTP/MyFTP.Test/TestData/Data.txt b/MyFTP/MyFTP.Test/TestData/Data.txt new file mode 100644 index 0000000..dc36f61 --- /dev/null +++ b/MyFTP/MyFTP.Test/TestData/Data.txt @@ -0,0 +1 @@ +qwerty \ No newline at end of file diff --git a/MyFTP/MyFTP.Test/TestData/File.txt b/MyFTP/MyFTP.Test/TestData/File.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/MyFTP/MyFTP.Test/TestData/File.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/MyFTP/MyFTP/Client.cs b/MyFTP/MyFTP/Client.cs index a6ce151..5141b4b 100644 --- a/MyFTP/MyFTP/Client.cs +++ b/MyFTP/MyFTP/Client.cs @@ -1,29 +1,77 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net.Sockets; using System.Threading.Tasks; namespace MyFTP { + /// + /// класс клиента для общения с сервером + /// public class Client { - private int _port; - private string _host; + private readonly int _port; + private readonly string _host; - Client(int port, string host) + public Client(int port, string host) { _port = port; _host = host; } - public async Task List(string path, Stream stream) - { - + /// + /// запрос на листинг файлов в папке по пути + /// + public async Task<(string name, bool isDir)[]> List(string path) + { + var client = new TcpClient(_host, _port); + using var stream = client.GetStream(); + var writer = new StreamWriter(stream); + await writer.WriteLineAsync($"1 {path}"); + await writer.FlushAsync(); + var reader = new StreamReader(stream); + var info = await reader.ReadLineAsync(); + var infoArray = info.Split(' '); + var size = Convert.ToInt32(infoArray[0]); + if (size == -1) + { + return null; + } + + var data = new (string name, bool isDir)[size]; + + for (int i = 1; i < infoArray.Length; i += 2) + { + var name = infoArray[i]; + var isDir = Convert.ToBoolean(infoArray[i + 1]); + data[(i - 1) / 2] = (name, isDir); + } + + return data; } - - public async Task Get(string path, Stream stream) + + /// + /// запрос на скачивание нужного файла + /// + public async Task<(long size, byte[] content)> Get(string path, Stream fileStream) { - + var client = new TcpClient(_host, _port); + using var stream = client.GetStream(); + var writer = new StreamWriter(stream); + await writer.WriteLineAsync($"2 {path}"); + await writer.FlushAsync(); + var reader = new StreamReader(stream); + var size = Convert.ToInt32(await reader.ReadLineAsync()); + if (size == -1) + { + throw new FileNotFoundException(); + } + + var content = new byte[size]; + await reader.BaseStream.ReadAsync(content, 0, size); + fileStream.Position = 0; + return (size, content); } } -} +} \ No newline at end of file diff --git a/MyFTP/MyFTP/Program.cs b/MyFTP/MyFTP/Program.cs new file mode 100644 index 0000000..4df809f --- /dev/null +++ b/MyFTP/MyFTP/Program.cs @@ -0,0 +1,18 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace MyFTP +{ + class Program + { + static void Main(string[] args) + { + + } + + } +} \ No newline at end of file diff --git a/MyFTP/MyFTP/Server.cs b/MyFTP/MyFTP/Server.cs index 2b8f233..893274d 100644 --- a/MyFTP/MyFTP/Server.cs +++ b/MyFTP/MyFTP/Server.cs @@ -8,32 +8,46 @@ namespace MyFTP { + /// + /// класс сервера для приема запросов от клиента + /// public class Server { private int _port; private readonly TcpListener _listener; - private CancellationTokenSource _cancellationToken; + private readonly CancellationTokenSource _cancellationToken = new CancellationTokenSource(); - Server(int port, string host, CancellationTokenSource cancellationToken) + public Server(int port, string host) { _port = port; _listener = new TcpListener(IPAddress.Parse(host), port); } + /// + /// старт приема запросов + /// public async Task StartServer() { _listener.Start(); - while (_cancellationToken.IsCancellationRequested) + while (!_cancellationToken.IsCancellationRequested) { var client = await _listener.AcceptTcpClientAsync(); - await Task.Run(() => Working(client)); + Working(client); } + + _listener.Stop(); } + /// + /// остановка приема запросов + /// public void StopServer() - => _cancellationToken.Cancel(); + => _cancellationToken.Cancel(); - public async Task Working(TcpClient client) + /// + /// метод для распределения запросов + /// + private async void Working(TcpClient client) { var stream = client.GetStream(); var reader = new StreamReader(stream); @@ -44,50 +58,54 @@ public async Task Working(TcpClient client) { case "1": await List(writer, path); - break; + break; case "2": - await Get(writer, path); - break; + await Get(writer, path, stream); + break; default: throw new ArgumentException(); } } - public async Task List(StreamWriter writer,string path) + private async Task List(StreamWriter writer, string path) { if (!Directory.Exists(path)) { await writer.WriteLineAsync("-1"); - return; + await writer.FlushAsync(); } var files = Directory.GetFiles(path); var directories = Directory.GetDirectories(path); var size = files.Length + directories.Length; - await writer.WriteAsync("{size}"); + string result = ""; foreach (var file in files) { - await writer.WriteAsync($" {file} false"); + result += $" {file} false"; } - - foreach (var directory in directories) + + foreach (var dir in directories) { - await writer.WriteAsync($" {directory} true"); + result += $" {dir} true"; } + await writer.WriteLineAsync(size.ToString() + result); + await writer.FlushAsync(); } - - public async Task Get(StreamWriter writer,string path) + + private async Task Get(StreamWriter writer, string path, NetworkStream stream) { if (!File.Exists(path)) { await writer.WriteLineAsync("-1"); - return; + await writer.FlushAsync(); } - var size = new FileInfo(path).Length; - await writer.WriteAsync($"{size}"); - /// write file + var file = new FileStream(path, FileMode.Open); + await writer.WriteLineAsync($"{file.Length} "); + await writer.FlushAsync(); + await file.CopyToAsync(stream); + await writer.FlushAsync(); } } } \ No newline at end of file From 89ed8034adb332c0fe72686adabdf959495c8e7e Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Wed, 27 Oct 2021 02:35:23 +0300 Subject: [PATCH 03/17] correct code and delete file --- MyFTP/MyFTP.Test/TestData/File.txt | 1 - MyFTP/MyFTP/Client.cs | 2 +- MyFTP/MyFTP/Server.cs | 5 +++-- 3 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 MyFTP/MyFTP.Test/TestData/File.txt diff --git a/MyFTP/MyFTP.Test/TestData/File.txt b/MyFTP/MyFTP.Test/TestData/File.txt deleted file mode 100644 index 5f28270..0000000 --- a/MyFTP/MyFTP.Test/TestData/File.txt +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/MyFTP/MyFTP/Client.cs b/MyFTP/MyFTP/Client.cs index 5141b4b..6ae928a 100644 --- a/MyFTP/MyFTP/Client.cs +++ b/MyFTP/MyFTP/Client.cs @@ -24,7 +24,7 @@ public Client(int port, string host) /// запрос на листинг файлов в папке по пути /// public async Task<(string name, bool isDir)[]> List(string path) - { + { var client = new TcpClient(_host, _port); using var stream = client.GetStream(); var writer = new StreamWriter(stream); diff --git a/MyFTP/MyFTP/Server.cs b/MyFTP/MyFTP/Server.cs index 893274d..4a56b55 100644 --- a/MyFTP/MyFTP/Server.cs +++ b/MyFTP/MyFTP/Server.cs @@ -66,7 +66,7 @@ private async void Working(TcpClient client) throw new ArgumentException(); } } - + private async Task List(StreamWriter writer, string path) { if (!Directory.Exists(path)) @@ -89,10 +89,11 @@ private async Task List(StreamWriter writer, string path) { result += $" {dir} true"; } + await writer.WriteLineAsync(size.ToString() + result); await writer.FlushAsync(); } - + private async Task Get(StreamWriter writer, string path, NetworkStream stream) { if (!File.Exists(path)) From 850857e564693d92113e53d019feb3f695e53fcc Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 22 Nov 2021 12:58:28 +0300 Subject: [PATCH 04/17] fix code --- MyFTP/ConsoleApp1/Client.cs | 64 ------------------------ MyFTP/MyFTP.Test/MyFTP.Test.csproj | 22 +++++++++ MyFTP/MyFTP.Test/MyFTPTest.cs | 68 ++++++++++++++++++++++++++ MyFTP/MyFTP.sln | 28 +++++++++++ MyFTP/MyFTP/Program.cs | 18 ------- MyFTP/{MyFTP => MyFTPClient}/Client.cs | 46 ++++++++++------- MyFTP/MyFTPClient/MyFTPClient.csproj | 10 ++++ MyFTP/MyFTPClient/Program.cs | 64 ++++++++++++++++++++++++ MyFTP/MyFTPServer/.dockerignore | 25 ++++++++++ MyFTP/MyFTPServer/Dockerfile | 18 +++++++ MyFTP/MyFTPServer/MyFTPServer.csproj | 9 ++++ MyFTP/MyFTPServer/Program.cs | 31 ++++++++++++ MyFTP/{MyFTP => MyFTPServer}/Server.cs | 31 ++++++------ 13 files changed, 316 insertions(+), 118 deletions(-) delete mode 100644 MyFTP/ConsoleApp1/Client.cs create mode 100644 MyFTP/MyFTP.Test/MyFTP.Test.csproj create mode 100644 MyFTP/MyFTP.Test/MyFTPTest.cs create mode 100644 MyFTP/MyFTP.sln delete mode 100644 MyFTP/MyFTP/Program.cs rename MyFTP/{MyFTP => MyFTPClient}/Client.cs (56%) create mode 100644 MyFTP/MyFTPClient/MyFTPClient.csproj create mode 100644 MyFTP/MyFTPClient/Program.cs create mode 100644 MyFTP/MyFTPServer/.dockerignore create mode 100644 MyFTP/MyFTPServer/Dockerfile create mode 100644 MyFTP/MyFTPServer/MyFTPServer.csproj create mode 100644 MyFTP/MyFTPServer/Program.cs rename MyFTP/{MyFTP => MyFTPServer}/Server.cs (83%) diff --git a/MyFTP/ConsoleApp1/Client.cs b/MyFTP/ConsoleApp1/Client.cs deleted file mode 100644 index b1c3dc2..0000000 --- a/MyFTP/ConsoleApp1/Client.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.IO; -using System.Net.Sockets; -using System.Threading.Tasks; - -namespace ConsoleApp1 -{ - public class Client - { - private readonly int _port; - private readonly string _host; - - public Client(int port, string host) - { - _port = port; - _host = host; - } - - public async Task<(string name, bool isDir)[]> List(string path) - { - using var client = new TcpClient(_host, _port); - await using var stream = client.GetStream(); - var writer = new StreamWriter(stream) {AutoFlush = true}; - await writer.WriteLineAsync($"1 {path}"); - var reader = new StreamReader(stream); - var size = Convert.ToInt32(await reader.ReadLineAsync()); - - if (size == -1) - { - return null; - } - - var data = new (string name, bool isDir)[size]; - - for (int i = 0; i < size; i++) - { - var name = await reader.ReadLineAsync(); - var isDir = Convert.ToBoolean(await reader.ReadLineAsync()); - data[i] = (name, isDir); - } - - return data; - } - - public async Task Get(string path, Stream fileStream) - { - var client = new TcpClient(_host, _port); - await using var stream = client.GetStream(); - var writer = new StreamWriter(stream) {AutoFlush = true}; - await writer.WriteLineAsync($"2 {path}"); - var reader = new StreamReader(stream); - var size = Convert.ToInt32(await reader.ReadLineAsync()); - if (size == -1) - { - throw new FileNotFoundException(); - } - - var content = new byte[size]; - await reader.BaseStream.ReadAsync(content, 0, size); - await stream.CopyToAsync(fileStream); - fileStream.Position = 0; - } - } -} \ No newline at end of file diff --git a/MyFTP/MyFTP.Test/MyFTP.Test.csproj b/MyFTP/MyFTP.Test/MyFTP.Test.csproj new file mode 100644 index 0000000..aa807e2 --- /dev/null +++ b/MyFTP/MyFTP.Test/MyFTP.Test.csproj @@ -0,0 +1,22 @@ + + + + net5.0 + + false + + + + + + + + + + + + + + + + diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs new file mode 100644 index 0000000..60a2492 --- /dev/null +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -0,0 +1,68 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using MyFTPClient; +using MyFTPServer; +using NUnit.Framework; + +namespace MyFTP.Test +{ + public class Tests + { + private Server _server; + private Client _client; + private Stream _fileStream; + private readonly CancellationTokenSource _cancellationToken = new (); + + [SetUp] + public void Setup() + { + _server = new Server("127.0.0.1", 80); + _client = new Client(80, "127.0.0.1"); + _fileStream = new MemoryStream(); + _server.StartServer(); + } + + [Test] + public void GetInvalidFileNameTest() + { + Assert.Throws(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait()); + _server.StopServer(); + } + + [Test] + public async Task ListInvalidFileNameTest() + { + Assert.Throws(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait()); + _server.StopServer(); + } + + [Test] + public async Task ListTest() + { + var data = await _client.List("../../../TestData", _cancellationToken); + _server.StopServer(); + 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); + } + + _server.StopServer(); + var result2 = File.ReadAllBytes(destination); + Assert.AreEqual(result, result2); + File.Delete(destination); + } + } +} \ No newline at end of file diff --git a/MyFTP/MyFTP.sln b/MyFTP/MyFTP.sln new file mode 100644 index 0000000..794b62f --- /dev/null +++ b/MyFTP/MyFTP.sln @@ -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 diff --git a/MyFTP/MyFTP/Program.cs b/MyFTP/MyFTP/Program.cs deleted file mode 100644 index 4df809f..0000000 --- a/MyFTP/MyFTP/Program.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; - -namespace MyFTP -{ - class Program - { - static void Main(string[] args) - { - - } - - } -} \ No newline at end of file diff --git a/MyFTP/MyFTP/Client.cs b/MyFTP/MyFTPClient/Client.cs similarity index 56% rename from MyFTP/MyFTP/Client.cs rename to MyFTP/MyFTPClient/Client.cs index 6ae928a..db8c082 100644 --- a/MyFTP/MyFTP/Client.cs +++ b/MyFTP/MyFTPClient/Client.cs @@ -2,9 +2,10 @@ using System.Collections.Generic; using System.IO; using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; -namespace MyFTP +namespace MyFTPClient { /// /// класс клиента для общения с сервером @@ -23,29 +24,33 @@ public Client(int port, string host) /// /// запрос на листинг файлов в папке по пути /// - public async Task<(string name, bool isDir)[]> List(string path) + public async Task<(string name, bool isDir)[]> List(string path, CancellationTokenSource tokenSource) { - var client = new TcpClient(_host, _port); - using var stream = client.GetStream(); - var writer = new StreamWriter(stream); + using var client = new TcpClient(); + await client.ConnectAsync(_host, _port); + 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 reader = new StreamReader(stream); var info = await reader.ReadLineAsync(); var infoArray = info.Split(' '); var size = Convert.ToInt32(infoArray[0]); if (size == -1) { - return null; + throw new ArgumentException(); } var data = new (string name, bool isDir)[size]; for (int i = 1; i < infoArray.Length; i += 2) { - var name = infoArray[i]; + if (tokenSource.IsCancellationRequested) + { + return null; + } var isDir = Convert.ToBoolean(infoArray[i + 1]); - data[(i - 1) / 2] = (name, isDir); + data[(i - 1) / 2] = (infoArray[i], isDir); } return data; @@ -54,24 +59,27 @@ public Client(int port, string host) /// /// запрос на скачивание нужного файла /// - public async Task<(long size, byte[] content)> Get(string path, Stream fileStream) + public async Task Get(string path, Stream fileStream, CancellationTokenSource tokenSource) { - var client = new TcpClient(_host, _port); - using var stream = client.GetStream(); - var writer = new StreamWriter(stream); + using var client = new TcpClient(_host, _port); + 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 reader = new StreamReader(stream); var size = Convert.ToInt32(await reader.ReadLineAsync()); + if (tokenSource.IsCancellationRequested) + { + throw new ArgumentException(); + } if (size == -1) { - throw new FileNotFoundException(); + throw new ArgumentException(); } - var content = new byte[size]; - await reader.BaseStream.ReadAsync(content, 0, size); - fileStream.Position = 0; - return (size, content); + await stream.CopyToAsync(fileStream); + + return size; } } } \ No newline at end of file diff --git a/MyFTP/MyFTPClient/MyFTPClient.csproj b/MyFTP/MyFTPClient/MyFTPClient.csproj new file mode 100644 index 0000000..42b41a9 --- /dev/null +++ b/MyFTP/MyFTPClient/MyFTPClient.csproj @@ -0,0 +1,10 @@ + + + + Exe + net5.0 + Windows + MyFTP + + + diff --git a/MyFTP/MyFTPClient/Program.cs b/MyFTP/MyFTPClient/Program.cs new file mode 100644 index 0000000..9add59a --- /dev/null +++ b/MyFTP/MyFTPClient/Program.cs @@ -0,0 +1,64 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace MyFTPClient +{ + 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(port, ip); + Console.WriteLine("Cписок запросов:"); + Console.WriteLine( + "List:\nФормат запроса:1 \npath - путь к директории относительно того места, где запущен сервер"); + Console.WriteLine( + "Get:\nФормат запроса:2 \npath1 - путь к файлу относительно того места, где запущен сервер\n" + + "npath2 - путь к файлу на локальной машине, где запущен клиент"); + Console.WriteLine("Введите exit, если хотите закрыть соединение с сервером"); + var request = Console.ReadLine().Split(' '); + var token = new CancellationTokenSource(); + while (request[0] != "exit" || !token.IsCancellationRequested) + { + if (request[0] == "1") + { + try + { + var response = await client.List(request[1], 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 response = client.Get(request[1], fstream, token); + } + catch (Exception e) + { + Console.WriteLine("Ошибка!"); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/MyFTP/MyFTPServer/.dockerignore b/MyFTP/MyFTPServer/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/MyFTP/MyFTPServer/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/MyFTP/MyFTPServer/Dockerfile b/MyFTP/MyFTPServer/Dockerfile new file mode 100644 index 0000000..9ac59bb --- /dev/null +++ b/MyFTP/MyFTPServer/Dockerfile @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build +WORKDIR /src +COPY ["MyFTPServer/MyFTPServer.csproj", "MyFTPServer/"] +RUN dotnet restore "MyFTPServer/MyFTPServer.csproj" +COPY . . +WORKDIR "/src/MyFTPServer" +RUN dotnet build "MyFTPServer.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "MyFTPServer.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "MyFTPServer.dll"] diff --git a/MyFTP/MyFTPServer/MyFTPServer.csproj b/MyFTP/MyFTPServer/MyFTPServer.csproj new file mode 100644 index 0000000..a184b89 --- /dev/null +++ b/MyFTP/MyFTPServer/MyFTPServer.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + Windows + + + diff --git a/MyFTP/MyFTPServer/Program.cs b/MyFTP/MyFTPServer/Program.cs new file mode 100644 index 0000000..14c2539 --- /dev/null +++ b/MyFTP/MyFTPServer/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; + +namespace MyFTPServer +{ + class Program + { + static async Task Main(string[] args) + { + Console.WriteLine("Введите IP сервер:"); + var ipAddress = Console.ReadLine(); + Console.WriteLine("Введите порт сервера:"); + var port = int.Parse(Console.ReadLine()); + try + { + var server = new Server(ipAddress, port); + await server.StartServer(); + Console.WriteLine("Введите /exit, чтобы остановить сервер"); + var command = ""; + while (command != "/exit") + { + command = Console.ReadLine(); + } + } + catch (Exception e) + { + Console.WriteLine("Ошибка!"); + } + } + } +} \ No newline at end of file diff --git a/MyFTP/MyFTP/Server.cs b/MyFTP/MyFTPServer/Server.cs similarity index 83% rename from MyFTP/MyFTP/Server.cs rename to MyFTP/MyFTPServer/Server.cs index 4a56b55..e6f9fe7 100644 --- a/MyFTP/MyFTP/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -1,25 +1,21 @@ -using System; -using System.Data; -using System.IO; +using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; -namespace MyFTP +namespace MyFTPServer { /// /// класс сервера для приема запросов от клиента /// public class Server { - private int _port; private readonly TcpListener _listener; - private readonly CancellationTokenSource _cancellationToken = new CancellationTokenSource(); + private readonly CancellationTokenSource _cancellationToken = new (); - public Server(int port, string host) + public Server(string host, int port) { - _port = port; _listener = new TcpListener(IPAddress.Parse(host), port); } @@ -49,21 +45,22 @@ public void StopServer() /// private async void Working(TcpClient client) { - var stream = client.GetStream(); - var reader = new StreamReader(stream); - var writer = new StreamWriter(stream); + using var stream = client.GetStream(); + using var reader = new StreamReader(stream); + using var writer = new StreamWriter(stream); var request = await reader.ReadLineAsync(); var (command, path) = (request?.Split()[0], request?.Split()[1]); switch (command) { case "1": await List(writer, path); - break; + break; case "2": await Get(writer, path, stream); - break; + break; default: - throw new ArgumentException(); + await writer.WriteAsync("Ваш протокол сломан!"); + break; } } @@ -72,9 +69,9 @@ private async Task List(StreamWriter writer, string path) if (!Directory.Exists(path)) { await writer.WriteLineAsync("-1"); - await writer.FlushAsync(); + return; } - + var files = Directory.GetFiles(path); var directories = Directory.GetDirectories(path); var size = files.Length + directories.Length; @@ -99,7 +96,7 @@ private async Task Get(StreamWriter writer, string path, NetworkStream stream) if (!File.Exists(path)) { await writer.WriteLineAsync("-1"); - await writer.FlushAsync(); + return; } var file = new FileStream(path, FileMode.Open); From 2ca4b93e86d9caed540bb5744e0c8dca70747a9d Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 6 Dec 2021 23:31:48 +0300 Subject: [PATCH 05/17] fix --- MyFTP/MyFTP.Test/MyFTP.Test.csproj | 3 +- MyFTP/MyFTP.Test/MyFTPTest.cs | 101 ++++++++-------- MyFTP/MyFTPClient/Client.cs | 123 ++++++++++---------- MyFTP/MyFTPClient/MyFTPClient.csproj | 2 +- MyFTP/MyFTPClient/Program.cs | 84 +++++--------- MyFTP/MyFTPServer/MyFTPServer.csproj | 2 +- MyFTP/MyFTPServer/Program.cs | 37 ++---- MyFTP/MyFTPServer/Server.cs | 167 +++++++++++++-------------- MyFTP/global.json | 7 ++ 9 files changed, 239 insertions(+), 287 deletions(-) create mode 100644 MyFTP/global.json diff --git a/MyFTP/MyFTP.Test/MyFTP.Test.csproj b/MyFTP/MyFTP.Test/MyFTP.Test.csproj index aa807e2..f0020ea 100644 --- a/MyFTP/MyFTP.Test/MyFTP.Test.csproj +++ b/MyFTP/MyFTP.Test/MyFTP.Test.csproj @@ -1,7 +1,7 @@ - net5.0 + net6.0 false @@ -14,7 +14,6 @@ - diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index 60a2492..9fe398f 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -2,67 +2,64 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -using MyFTPClient; -using MyFTPServer; using NUnit.Framework; -namespace MyFTP.Test +public class Tests { - public class Tests + private Server _server; + private Client _client; + private Stream _fileStream; + private readonly CancellationToken _cancellationToken = new (); + + [SetUp] + public void Setup() { - private Server _server; - private Client _client; - private Stream _fileStream; - private readonly CancellationTokenSource _cancellationToken = new (); + _server = new Server("127.0.0.1", 80); + _client = new Client("127.0.0.1", 80); + _fileStream = new MemoryStream(); + _=_server.StartServer(); + } - [SetUp] - public void Setup() - { - _server = new Server("127.0.0.1", 80); - _client = new Client(80, "127.0.0.1"); - _fileStream = new MemoryStream(); - _server.StartServer(); - } + [TearDown] + public void TearDown() + { + _server.StopServer(); + } - [Test] - public void GetInvalidFileNameTest() - { - Assert.Throws(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait()); - _server.StopServer(); - } + [Test] + public void GetInvalidFileNameTest() + { + Assert.ThrowsAsync(() => Task.Run(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait())); + } - [Test] - public async Task ListInvalidFileNameTest() - { - Assert.Throws(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait()); - _server.StopServer(); - } + [Test] + public async Task ListInvalidFileNameTest() + { + Assert.ThrowsAsync(() => Task.Run(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait())); + } - [Test] - public async Task ListTest() - { - var data = await _client.List("../../../TestData", _cancellationToken); - _server.StopServer(); - Assert.AreEqual("../../../TestData\\Data.txt", data[0].name); - Assert.AreEqual(false, data[0].isDir); - } + [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); - } - - _server.StopServer(); - var result2 = File.ReadAllBytes(destination); - Assert.AreEqual(result, result2); - File.Delete(destination); + [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); } } \ No newline at end of file diff --git a/MyFTP/MyFTPClient/Client.cs b/MyFTP/MyFTPClient/Client.cs index db8c082..370ba89 100644 --- a/MyFTP/MyFTPClient/Client.cs +++ b/MyFTP/MyFTPClient/Client.cs @@ -1,85 +1,78 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net.Sockets; -using System.Threading; +using System.Net.Sockets; using System.Threading.Tasks; -namespace MyFTPClient +/// +/// класс клиента для общения с сервером +/// +public class Client { + private readonly int _port; + private readonly string _host; + + public Client(string host, int port ) + { + _host = host; + _port = port; + } + /// - /// класс клиента для общения с сервером + /// запрос на листинг файлов в папке по пути /// - public class Client + public async Task<(string name, bool isDir)[]> List(string path, CancellationToken cancellationToken) { - private readonly int _port; - private readonly string _host; - - public Client(int port, string host) + 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) { - _port = port; - _host = host; + throw new ArgumentException(); } - /// - /// запрос на листинг файлов в папке по пути - /// - public async Task<(string name, bool isDir)[]> List(string path, CancellationTokenSource tokenSource) + var data = new (string name, bool isDir)[size]; + + for (int i = 1; i < infoArray.Length; i += 2) { - using var client = new TcpClient(); - await client.ConnectAsync(_host, _port); - 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) + if (cancellationToken.IsCancellationRequested) { - throw new ArgumentException(); + return null; } + var isDir = Convert.ToBoolean(infoArray[i + 1]); + data[(i - 1) / 2] = (infoArray[i], isDir); + } - var data = new (string name, bool isDir)[size]; - - for (int i = 1; i < infoArray.Length; i += 2) - { - if (tokenSource.IsCancellationRequested) - { - return null; - } - var isDir = Convert.ToBoolean(infoArray[i + 1]); - data[(i - 1) / 2] = (infoArray[i], isDir); - } + return data; + } - return data; + /// + /// запрос на скачивание нужного файла + /// + public async Task Get(string path, Stream fileStream, CancellationToken cancellationToken) + { + using var client = new TcpClient(_host, _port); + 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 (cancellationToken.IsCancellationRequested) + { + throw new ArgumentException(); } - - /// - /// запрос на скачивание нужного файла - /// - public async Task Get(string path, Stream fileStream, CancellationTokenSource tokenSource) + if (size == -1) { - using var client = new TcpClient(_host, _port); - 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 (tokenSource.IsCancellationRequested) - { - throw new ArgumentException(); - } - if (size == -1) - { - throw new ArgumentException(); - } + throw new ArgumentException(); + } - await stream.CopyToAsync(fileStream); + await stream.CopyToAsync(fileStream); - return size; - } + return size; } } \ No newline at end of file diff --git a/MyFTP/MyFTPClient/MyFTPClient.csproj b/MyFTP/MyFTPClient/MyFTPClient.csproj index 42b41a9..8621866 100644 --- a/MyFTP/MyFTPClient/MyFTPClient.csproj +++ b/MyFTP/MyFTPClient/MyFTPClient.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 Windows MyFTP diff --git a/MyFTP/MyFTPClient/Program.cs b/MyFTP/MyFTPClient/Program.cs index 9add59a..d239eca 100644 --- a/MyFTP/MyFTPClient/Program.cs +++ b/MyFTP/MyFTPClient/Program.cs @@ -1,63 +1,39 @@ -using System; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; +global using System.Threading; +global using System; +global using System.IO; -namespace MyFTPClient +var client = new Client(args[0], Convert.ToInt32(args[1])); +var request = Console.ReadLine().Split(' '); +var token = new CancellationToken(); +while (request[0] != "exit" || !token.IsCancellationRequested) { - class Program + if (request[0] == "1") { - static async Task Main(string[] args) + try { - Console.WriteLine("Введите IP сервера:"); - var ip = Console.ReadLine(); - Console.WriteLine("Введите порт:"); - int.TryParse(Console.ReadLine(), out var port); - var client = new Client(port, ip); - Console.WriteLine("Cписок запросов:"); - Console.WriteLine( - "List:\nФормат запроса:1 \npath - путь к директории относительно того места, где запущен сервер"); - Console.WriteLine( - "Get:\nФормат запроса:2 \npath1 - путь к файлу относительно того места, где запущен сервер\n" + - "npath2 - путь к файлу на локальной машине, где запущен клиент"); - Console.WriteLine("Введите exit, если хотите закрыть соединение с сервером"); - var request = Console.ReadLine().Split(' '); - var token = new CancellationTokenSource(); - while (request[0] != "exit" || !token.IsCancellationRequested) + var response = await client.List(request[1], token); + foreach (var file in response) { - if (request[0] == "1") - { - try - { - var response = await client.List(request[1], token); - foreach (var file in response) - { - Console.WriteLine($"{file.Item1} {file.Item2}"); - } - } - catch (Exception e) - { - Console.WriteLine("Ошибка!"); - } - } + Console.WriteLine($"{file.Item1} {file.Item2}"); + } + } + catch (Exception) + { + Console.WriteLine("Ошибка!"); + } + } - if (request[0] == "2") - { - using (var fstream = new FileStream(request[2], FileMode.OpenOrCreate)) - { - try - { - var response = client.Get(request[1], fstream, token); - } - 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, token); + } + catch (Exception) + { + Console.WriteLine("Ошибка!"); } } } diff --git a/MyFTP/MyFTPServer/MyFTPServer.csproj b/MyFTP/MyFTPServer/MyFTPServer.csproj index a184b89..21cce88 100644 --- a/MyFTP/MyFTPServer/MyFTPServer.csproj +++ b/MyFTP/MyFTPServer/MyFTPServer.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 Windows diff --git a/MyFTP/MyFTPServer/Program.cs b/MyFTP/MyFTPServer/Program.cs index 14c2539..aa1825c 100644 --- a/MyFTP/MyFTPServer/Program.cs +++ b/MyFTP/MyFTPServer/Program.cs @@ -1,31 +1,12 @@ -using System; -using System.Threading.Tasks; +global using System; +global using System.Threading.Tasks; -namespace MyFTPServer +try { - class Program - { - static async Task Main(string[] args) - { - Console.WriteLine("Введите IP сервер:"); - var ipAddress = Console.ReadLine(); - Console.WriteLine("Введите порт сервера:"); - var port = int.Parse(Console.ReadLine()); - try - { - var server = new Server(ipAddress, port); - await server.StartServer(); - Console.WriteLine("Введите /exit, чтобы остановить сервер"); - var command = ""; - while (command != "/exit") - { - command = Console.ReadLine(); - } - } - catch (Exception e) - { - Console.WriteLine("Ошибка!"); - } - } - } + var server = new Server(args[0], Convert.ToInt32(args[1])); + await server.StartServer(); +} +catch (Exception) +{ + Console.WriteLine("Ошибка!"); } \ No newline at end of file diff --git a/MyFTP/MyFTPServer/Server.cs b/MyFTP/MyFTPServer/Server.cs index e6f9fe7..d39537f 100644 --- a/MyFTP/MyFTPServer/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -2,108 +2,107 @@ using System.Net; using System.Net.Sockets; using System.Threading; -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Text; -namespace MyFTPServer +/// +/// класс сервера для приема запросов от клиента +/// +public class Server { + private readonly TcpListener _listener; + private readonly CancellationTokenSource _cancellationToken = new (); + + public Server(string host, int port) + { + _listener = new TcpListener(IPAddress.Parse(host), port); + } + /// - /// класс сервера для приема запросов от клиента + /// старт приема запросов /// - public class Server + public async Task StartServer() { - private readonly TcpListener _listener; - private readonly CancellationTokenSource _cancellationToken = new (); - - public Server(string host, int port) - { - _listener = new TcpListener(IPAddress.Parse(host), port); - } - - /// - /// старт приема запросов - /// - public async Task StartServer() + var task = new List(); + _listener.Start(); + while (!_cancellationToken.IsCancellationRequested) { - _listener.Start(); - while (!_cancellationToken.IsCancellationRequested) - { - var client = await _listener.AcceptTcpClientAsync(); - Working(client); - } - - _listener.Stop(); + var client = await _listener.AcceptTcpClientAsync(); + task.Add(Working(client)); } + await Task.WhenAll(task); + _listener.Stop(); + } - /// - /// остановка приема запросов - /// - public void StopServer() - => _cancellationToken.Cancel(); + /// + /// остановка приема запросов + /// + public void StopServer() + => _cancellationToken.Cancel(); - /// - /// метод для распределения запросов - /// - private async void Working(TcpClient client) + /// + /// метод для распределения запросов + /// + private async Task Working(TcpClient client) + { + using var stream = client.GetStream(); + using var reader = new StreamReader(stream); + using var writer = new StreamWriter(stream); + var request = await reader.ReadLineAsync(); + var (command, path) = (request?.Split()[0], request?.Split()[1]); + switch (command) { - using var stream = client.GetStream(); - using var reader = new StreamReader(stream); - using var writer = new StreamWriter(stream); - var request = await reader.ReadLineAsync(); - var (command, path) = (request?.Split()[0], request?.Split()[1]); - switch (command) - { - case "1": - await List(writer, path); - break; - case "2": - await Get(writer, path, stream); - break; - default: - await writer.WriteAsync("Ваш протокол сломан!"); - break; - } + case "1": + await List(writer, path); + break; + case "2": + await Get(writer, path, stream); + break; + default: + await writer.WriteAsync("Ваш протокол сломан!"); + break; } + } - private async Task List(StreamWriter writer, string path) + private async Task List(StreamWriter writer, string path) + { + if (!Directory.Exists(path)) { - if (!Directory.Exists(path)) - { - await writer.WriteLineAsync("-1"); - return; - } + await writer.WriteLineAsync("-1"); + return; + } - var files = Directory.GetFiles(path); - var directories = Directory.GetDirectories(path); - var size = files.Length + directories.Length; - - string result = ""; - foreach (var file in files) - { - result += $" {file} false"; - } - - foreach (var dir in directories) - { - result += $" {dir} true"; - } - - await writer.WriteLineAsync(size.ToString() + result); - await writer.FlushAsync(); + var files = Directory.GetFiles(path); + var directories = Directory.GetDirectories(path); + var size = files.Length + directories.Length; + var result = new StringBuilder(); + result.Append(size).ToString(); + foreach (var file in files) + { + result.Append($" {file} false"); } - private async Task Get(StreamWriter writer, string path, NetworkStream stream) + foreach (var dir in directories) { - if (!File.Exists(path)) - { - await writer.WriteLineAsync("-1"); - return; - } + result.Append($" {dir} true"); + } + + await writer.WriteLineAsync(size.ToString() + result); + await writer.FlushAsync(); + } - var file = new FileStream(path, FileMode.Open); - await writer.WriteLineAsync($"{file.Length} "); - await writer.FlushAsync(); - await file.CopyToAsync(stream); - await writer.FlushAsync(); + private async Task Get(StreamWriter writer, string path, NetworkStream stream) + { + if (!File.Exists(path)) + { + await writer.WriteLineAsync("-1"); + return; } + + var file = new FileStream(path, FileMode.Open); + await writer.WriteLineAsync($"{file.Length} "); + await writer.FlushAsync(); + await file.CopyToAsync(stream); + await writer.FlushAsync(); } } \ No newline at end of file diff --git a/MyFTP/global.json b/MyFTP/global.json new file mode 100644 index 0000000..f443bd4 --- /dev/null +++ b/MyFTP/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "6.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} \ No newline at end of file From 72fe38b5154e5efca4ebee5dcf0f3d9432e1498f Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 7 Dec 2021 00:37:46 +0300 Subject: [PATCH 06/17] add global.json --- MyFTP/MyFTP.Test/global.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 MyFTP/MyFTP.Test/global.json diff --git a/MyFTP/MyFTP.Test/global.json b/MyFTP/MyFTP.Test/global.json new file mode 100644 index 0000000..f443bd4 --- /dev/null +++ b/MyFTP/MyFTP.Test/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "6.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} \ No newline at end of file From 5f15a7ed59ea456f46b31b3ae25fef180811424c Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 7 Dec 2021 01:09:25 +0300 Subject: [PATCH 07/17] fix --- MyFTP/MyFTP.Test/MyFTPTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index 9fe398f..3a01834 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -17,7 +17,7 @@ public void Setup() _server = new Server("127.0.0.1", 80); _client = new Client("127.0.0.1", 80); _fileStream = new MemoryStream(); - _=_server.StartServer(); + _server.StartServer(); } [TearDown] From a32e6ac9b7bc4ea90aa2a454ff8ce3b5fcf05ee9 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 7 Dec 2021 11:25:17 +0300 Subject: [PATCH 08/17] fix tests --- MyFTP/MyFTP.Test/MyFTPTest.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index 3a01834..f5773cd 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -9,7 +9,7 @@ public class Tests private Server _server; private Client _client; private Stream _fileStream; - private readonly CancellationToken _cancellationToken = new (); + private CancellationToken _cancellationToken; [SetUp] public void Setup() @@ -17,7 +17,8 @@ public void Setup() _server = new Server("127.0.0.1", 80); _client = new Client("127.0.0.1", 80); _fileStream = new MemoryStream(); - _server.StartServer(); + _cancellationToken = new (); + _server.StartServer();fi } [TearDown] From e85010e1e2e57ba50026e3025ec369ec9915edda Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 7 Dec 2021 11:25:47 +0300 Subject: [PATCH 09/17] correct --- MyFTP/MyFTP.Test/MyFTPTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index f5773cd..60cb0d8 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -18,7 +18,7 @@ public void Setup() _client = new Client("127.0.0.1", 80); _fileStream = new MemoryStream(); _cancellationToken = new (); - _server.StartServer();fi + _server.StartServer(); } [TearDown] From 9426a1784bbbc94fce502e135bc3326b32799249 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 7 Dec 2021 11:45:48 +0300 Subject: [PATCH 10/17] try fix --- MyFTP/MyFTP.Test/MyFTP.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MyFTP/MyFTP.Test/MyFTP.Test.csproj b/MyFTP/MyFTP.Test/MyFTP.Test.csproj index f0020ea..dcfd5bc 100644 --- a/MyFTP/MyFTP.Test/MyFTP.Test.csproj +++ b/MyFTP/MyFTP.Test/MyFTP.Test.csproj @@ -7,7 +7,7 @@ - + From 31c11e0596f9f46b4c121f0605a7bb873c777c9f Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 14 Feb 2022 11:48:55 +0300 Subject: [PATCH 11/17] change --- MyFTP/MyFTPClient/Client.cs | 2 +- MyFTP/MyFTPServer/Server.cs | 6 +++--- MyFTP/global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MyFTP/MyFTPClient/Client.cs b/MyFTP/MyFTPClient/Client.cs index 370ba89..3a14ec2 100644 --- a/MyFTP/MyFTPClient/Client.cs +++ b/MyFTP/MyFTPClient/Client.cs @@ -32,7 +32,7 @@ public Client(string host, int port ) var size = Convert.ToInt32(infoArray[0]); if (size == -1) { - throw new ArgumentException(); + throw new Exception(); } var data = new (string name, bool isDir)[size]; diff --git a/MyFTP/MyFTPServer/Server.cs b/MyFTP/MyFTPServer/Server.cs index d39537f..d9f3beb 100644 --- a/MyFTP/MyFTPServer/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -11,7 +11,7 @@ public class Server { private readonly TcpListener _listener; - private readonly CancellationTokenSource _cancellationToken = new (); + private readonly CancellationTokenSource _tokenSource = new (); public Server(string host, int port) { @@ -25,7 +25,7 @@ public async Task StartServer() { var task = new List(); _listener.Start(); - while (!_cancellationToken.IsCancellationRequested) + while (!_tokenSource.IsCancellationRequested) { var client = await _listener.AcceptTcpClientAsync(); task.Add(Working(client)); @@ -38,7 +38,7 @@ public async Task StartServer() /// остановка приема запросов /// public void StopServer() - => _cancellationToken.Cancel(); + => _tokenSource.Cancel(); /// /// метод для распределения запросов diff --git a/MyFTP/global.json b/MyFTP/global.json index f443bd4..97dd873 100644 --- a/MyFTP/global.json +++ b/MyFTP/global.json @@ -2,6 +2,6 @@ "sdk": { "version": "6.0", "rollForward": "latestMajor", - "allowPrerelease": true + "allowPrerelease": false } } \ No newline at end of file From f470b1f382727c1c8052d86260e75d63e9f94899 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 14 Feb 2022 12:25:02 +0300 Subject: [PATCH 12/17] delete files --- MyFTP/MyFTP.Test/global.json | 7 ------- MyFTP/MyFTPClient/MyFTPClient.csproj | 2 -- MyFTP/MyFTPServer/.dockerignore | 25 ------------------------- MyFTP/MyFTPServer/Dockerfile | 18 ------------------ MyFTP/MyFTPServer/MyFTPServer.csproj | 1 - 5 files changed, 53 deletions(-) delete mode 100644 MyFTP/MyFTP.Test/global.json delete mode 100644 MyFTP/MyFTPServer/.dockerignore delete mode 100644 MyFTP/MyFTPServer/Dockerfile diff --git a/MyFTP/MyFTP.Test/global.json b/MyFTP/MyFTP.Test/global.json deleted file mode 100644 index f443bd4..0000000 --- a/MyFTP/MyFTP.Test/global.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "sdk": { - "version": "6.0", - "rollForward": "latestMajor", - "allowPrerelease": true - } -} \ No newline at end of file diff --git a/MyFTP/MyFTPClient/MyFTPClient.csproj b/MyFTP/MyFTPClient/MyFTPClient.csproj index 8621866..7b96d01 100644 --- a/MyFTP/MyFTPClient/MyFTPClient.csproj +++ b/MyFTP/MyFTPClient/MyFTPClient.csproj @@ -3,8 +3,6 @@ Exe net6.0 - Windows - MyFTP diff --git a/MyFTP/MyFTPServer/.dockerignore b/MyFTP/MyFTPServer/.dockerignore deleted file mode 100644 index cd967fc..0000000 --- a/MyFTP/MyFTPServer/.dockerignore +++ /dev/null @@ -1,25 +0,0 @@ -**/.dockerignore -**/.env -**/.git -**/.gitignore -**/.project -**/.settings -**/.toolstarget -**/.vs -**/.vscode -**/.idea -**/*.*proj.user -**/*.dbmdl -**/*.jfm -**/azds.yaml -**/bin -**/charts -**/docker-compose* -**/Dockerfile* -**/node_modules -**/npm-debug.log -**/obj -**/secrets.dev.yaml -**/values.dev.yaml -LICENSE -README.md \ No newline at end of file diff --git a/MyFTP/MyFTPServer/Dockerfile b/MyFTP/MyFTPServer/Dockerfile deleted file mode 100644 index 9ac59bb..0000000 --- a/MyFTP/MyFTPServer/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base -WORKDIR /app - -FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build -WORKDIR /src -COPY ["MyFTPServer/MyFTPServer.csproj", "MyFTPServer/"] -RUN dotnet restore "MyFTPServer/MyFTPServer.csproj" -COPY . . -WORKDIR "/src/MyFTPServer" -RUN dotnet build "MyFTPServer.csproj" -c Release -o /app/build - -FROM build AS publish -RUN dotnet publish "MyFTPServer.csproj" -c Release -o /app/publish - -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "MyFTPServer.dll"] diff --git a/MyFTP/MyFTPServer/MyFTPServer.csproj b/MyFTP/MyFTPServer/MyFTPServer.csproj index 21cce88..7b96d01 100644 --- a/MyFTP/MyFTPServer/MyFTPServer.csproj +++ b/MyFTP/MyFTPServer/MyFTPServer.csproj @@ -3,7 +3,6 @@ Exe net6.0 - Windows From a4ba4e9e9a0e6a23aee33f8c5aed6f5cf9d0c8cc Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 14 Feb 2022 13:32:20 +0300 Subject: [PATCH 13/17] update appveyor.yml --- MyFTP/global.json | 2 +- appveyor.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/MyFTP/global.json b/MyFTP/global.json index 97dd873..c14434a 100644 --- a/MyFTP/global.json +++ b/MyFTP/global.json @@ -1,7 +1,7 @@ { "sdk": { "version": "6.0", - "rollForward": "latestMajor", + "rollForward": "minor", "allowPrerelease": false } } \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 9809100..d79f319 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,6 @@ +image: Visual Studio 2022 + + build_script: - For /R %%I in (*.sln) do dotnet test %%I test: of \ No newline at end of file From 41a56648fa4be2442ded5368fba4eee7be9e09a1 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 14 Mar 2022 12:58:11 +0300 Subject: [PATCH 14/17] not all fix --- MyFTP/MyFTP.Test/MyFTPTest.cs | 8 +++-- MyFTP/MyFTPClient/Client.cs | 21 ++++++------ MyFTP/MyFTPClient/Program.cs | 63 +++++++++++++++++++---------------- MyFTP/MyFTPServer/Program.cs | 32 +++++++++++++----- MyFTP/MyFTPServer/Server.cs | 5 ++- 5 files changed, 77 insertions(+), 52 deletions(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index 60cb0d8..708eb83 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -2,6 +2,8 @@ using System.IO; using System.Threading; using System.Threading.Tasks; +using MyFTPClient; +using MyFTPServer; using NUnit.Framework; public class Tests @@ -18,7 +20,7 @@ public void Setup() _client = new Client("127.0.0.1", 80); _fileStream = new MemoryStream(); _cancellationToken = new (); - _server.StartServer(); + _= _server.StartServer(); } [TearDown] @@ -34,8 +36,8 @@ public void GetInvalidFileNameTest() } [Test] - public async Task ListInvalidFileNameTest() - { + public void ListInvalidFileNameTest() + { Assert.ThrowsAsync(() => Task.Run(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait())); } diff --git a/MyFTP/MyFTPClient/Client.cs b/MyFTP/MyFTPClient/Client.cs index 3a14ec2..7448cb3 100644 --- a/MyFTP/MyFTPClient/Client.cs +++ b/MyFTP/MyFTPClient/Client.cs @@ -1,4 +1,9 @@ -using System.Net.Sockets; +namespace MyFTPClient; + +using System; +using System.IO; +using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; /// @@ -32,17 +37,14 @@ public Client(string host, int port ) var size = Convert.ToInt32(infoArray[0]); if (size == -1) { - throw new Exception(); + throw new ArgumentException(); } var data = new (string name, bool isDir)[size]; for (int i = 1; i < infoArray.Length; i += 2) { - if (cancellationToken.IsCancellationRequested) - { - return null; - } + var isDir = Convert.ToBoolean(infoArray[i + 1]); data[(i - 1) / 2] = (infoArray[i], isDir); } @@ -56,22 +58,19 @@ public Client(string host, int port ) public async Task Get(string path, Stream fileStream, CancellationToken cancellationToken) { using var client = new TcpClient(_host, _port); + 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 (cancellationToken.IsCancellationRequested) - { - throw new ArgumentException(); - } if (size == -1) { throw new ArgumentException(); } - await stream.CopyToAsync(fileStream); + await stream.CopyToAsync(fileStream, cancellationToken); return size; } diff --git a/MyFTP/MyFTPClient/Program.cs b/MyFTP/MyFTPClient/Program.cs index d239eca..c473760 100644 --- a/MyFTP/MyFTPClient/Program.cs +++ b/MyFTP/MyFTPClient/Program.cs @@ -1,39 +1,46 @@ -global using System.Threading; -global using System; -global using System.IO; +namespace MyFTPClient; -var client = new Client(args[0], Convert.ToInt32(args[1])); -var request = Console.ReadLine().Split(' '); -var token = new CancellationToken(); -while (request[0] != "exit" || !token.IsCancellationRequested) +using System.Threading; +using System; +using System.IO; + +public class Program { - if (request[0] == "1") + public async void main(string[] args) { - try + var client = new Client(args[0], Convert.ToInt32(args[1])); + var token = new CancellationToken(); + while (args[0] != "exit" || !token.IsCancellationRequested) { - var response = await client.List(request[1], token); - foreach (var file in response) + if (args[0] == "1") { - Console.WriteLine($"{file.Item1} {file.Item2}"); + try + { + var response = await client.List(args[1], token); + foreach (var file in response) + { + Console.WriteLine($"{file.Item1} {file.Item2}"); + } + } + catch (ArgumentException) + { + Console.WriteLine("Ошибка!"); + } } - } - catch (Exception) - { - Console.WriteLine("Ошибка!"); - } - } - if (request[0] == "2") - { - using (var fstream = new FileStream(request[2], FileMode.OpenOrCreate)) - { - try - { - var response = client.Get(request[1], fstream, token); - } - catch (Exception) + if (args[0] == "2") { - Console.WriteLine("Ошибка!"); + using (var fstream = new FileStream(args[2], FileMode.OpenOrCreate)) + { + try + { + var response = client.Get(args[1], fstream, token); + } + catch (ArgumentException) + { + Console.WriteLine("Ошибка!"); + } + } } } } diff --git a/MyFTP/MyFTPServer/Program.cs b/MyFTP/MyFTPServer/Program.cs index aa1825c..2e11ea1 100644 --- a/MyFTP/MyFTPServer/Program.cs +++ b/MyFTP/MyFTPServer/Program.cs @@ -1,12 +1,26 @@ -global using System; -global using System.Threading.Tasks; +namespace MyFTPServer; -try +using System; +using System.Threading.Tasks; + +public class Program { - var server = new Server(args[0], Convert.ToInt32(args[1])); - await server.StartServer(); + public async void main(string[] args) + { + try + { + var server = new Server(args[0], Convert.ToInt32(args[1])); + await server.StartServer(); + Console.WriteLine("Введите !exit, чтобы остановить сервер"); + var command = ""; + while (command != "!exit") + { + command = Console.ReadLine(); + } + } + catch (ArgumentException) + { + Console.WriteLine("Ошибка!"); + } + } } -catch (Exception) -{ - Console.WriteLine("Ошибка!"); -} \ No newline at end of file diff --git a/MyFTP/MyFTPServer/Server.cs b/MyFTP/MyFTPServer/Server.cs index d9f3beb..b589be3 100644 --- a/MyFTP/MyFTPServer/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -1,9 +1,12 @@ -using System.IO; +namespace MyFTPServer; + +using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.Collections.Generic; using System.Text; +using System.Threading.Tasks; /// /// класс сервера для приема запросов от клиента From 82e0df4e64a85d42c60e059cf3b301ee50536273 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 22 Mar 2022 00:53:35 +0300 Subject: [PATCH 15/17] fix code --- MyFTP/MyFTP.Test/MyFTPTest.cs | 25 +++++++++++++++++++++++-- MyFTP/MyFTPClient/Client.cs | 6 +++--- MyFTP/MyFTPClient/Program.cs | 7 ++++--- MyFTP/MyFTPServer/Program.cs | 2 +- MyFTP/MyFTPServer/Server.cs | 3 +++ 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index 708eb83..8995ca5 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -21,6 +21,7 @@ public void Setup() _fileStream = new MemoryStream(); _cancellationToken = new (); _= _server.StartServer(); + Thread.Sleep(5000); } [TearDown] @@ -32,13 +33,13 @@ public void TearDown() [Test] public void GetInvalidFileNameTest() { - Assert.ThrowsAsync(() => Task.Run(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait())); + Assert.ThrowsAsync(() => _client.Get("Text.txt", _fileStream, _cancellationToken)); } [Test] public void ListInvalidFileNameTest() { - Assert.ThrowsAsync(() => Task.Run(() => _client.Get("Text.txt", _fileStream, _cancellationToken).Wait())); + Assert.ThrowsAsync(() => _client.Get("Text.txt", _fileStream, _cancellationToken)); } [Test] @@ -65,4 +66,24 @@ public async Task GetTest() Assert.AreEqual(result, result2); File.Delete(destination); } + + [Test] + public void ParallelClientConnection() + { + var clients = new Task[2]; + 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(); + } + } } \ No newline at end of file diff --git a/MyFTP/MyFTPClient/Client.cs b/MyFTP/MyFTPClient/Client.cs index 7448cb3..5f79701 100644 --- a/MyFTP/MyFTPClient/Client.cs +++ b/MyFTP/MyFTPClient/Client.cs @@ -37,7 +37,7 @@ public Client(string host, int port ) var size = Convert.ToInt32(infoArray[0]); if (size == -1) { - throw new ArgumentException(); + throw new FileNotFoundException(); } var data = new (string name, bool isDir)[size]; @@ -57,7 +57,7 @@ public Client(string host, int port ) /// public async Task Get(string path, Stream fileStream, CancellationToken cancellationToken) { - using var client = new TcpClient(_host, _port); + using var client = new TcpClient(); await client.ConnectAsync(_host, _port, cancellationToken); await using var stream = client.GetStream(); await using var writer = new StreamWriter(stream); @@ -67,7 +67,7 @@ public async Task Get(string path, Stream fileStream, CancellationToken ca var size = Convert.ToInt32(await reader.ReadLineAsync()); if (size == -1) { - throw new ArgumentException(); + throw new FileNotFoundException(); } await stream.CopyToAsync(fileStream, cancellationToken); diff --git a/MyFTP/MyFTPClient/Program.cs b/MyFTP/MyFTPClient/Program.cs index c473760..593b2c5 100644 --- a/MyFTP/MyFTPClient/Program.cs +++ b/MyFTP/MyFTPClient/Program.cs @@ -3,10 +3,11 @@ using System.Threading; using System; using System.IO; +using System.Threading.Tasks; public class Program { - public async void main(string[] args) + public static async Task Main(string[] args) { var client = new Client(args[0], Convert.ToInt32(args[1])); var token = new CancellationToken(); @@ -22,7 +23,7 @@ public async void main(string[] args) Console.WriteLine($"{file.Item1} {file.Item2}"); } } - catch (ArgumentException) + catch (FileNotFoundException) { Console.WriteLine("Ошибка!"); } @@ -36,7 +37,7 @@ public async void main(string[] args) { var response = client.Get(args[1], fstream, token); } - catch (ArgumentException) + catch (FileNotFoundException) { Console.WriteLine("Ошибка!"); } diff --git a/MyFTP/MyFTPServer/Program.cs b/MyFTP/MyFTPServer/Program.cs index 2e11ea1..b3f2c12 100644 --- a/MyFTP/MyFTPServer/Program.cs +++ b/MyFTP/MyFTPServer/Program.cs @@ -5,7 +5,7 @@ public class Program { - public async void main(string[] args) + public static async Task Main(string[] args) { try { diff --git a/MyFTP/MyFTPServer/Server.cs b/MyFTP/MyFTPServer/Server.cs index b589be3..11622d8 100644 --- a/MyFTP/MyFTPServer/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -61,6 +61,9 @@ private async Task Working(TcpClient client) case "2": await Get(writer, path, stream); break; + case "!exit": + StopServer(); + break; default: await writer.WriteAsync("Ваш протокол сломан!"); break; From ec465c868e9355fa06baf179ade7fd7978410674 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 4 Apr 2022 00:13:11 +0300 Subject: [PATCH 16/17] fix bugs --- MyFTP/MyFTP.Test/MyFTPTest.cs | 4 +++- MyFTP/MyFTPClient/Client.cs | 9 +++++--- MyFTP/MyFTPClient/Program.cs | 40 ++++++++++++++++++++++------------- MyFTP/MyFTPServer/Program.cs | 9 +++++++- MyFTP/MyFTPServer/Server.cs | 2 +- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index 8995ca5..a5eb1f7 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -1,3 +1,5 @@ +namespace MyFTP.Test; + using System; using System.IO; using System.Threading; @@ -20,7 +22,7 @@ public void Setup() _client = new Client("127.0.0.1", 80); _fileStream = new MemoryStream(); _cancellationToken = new (); - _= _server.StartServer(); + _server.StartServer(); Thread.Sleep(5000); } diff --git a/MyFTP/MyFTPClient/Client.cs b/MyFTP/MyFTPClient/Client.cs index 5f79701..3df7009 100644 --- a/MyFTP/MyFTPClient/Client.cs +++ b/MyFTP/MyFTPClient/Client.cs @@ -1,6 +1,7 @@ namespace MyFTPClient; using System; +using System.Collections.Generic; using System.IO; using System.Net.Sockets; using System.Threading; @@ -40,16 +41,18 @@ public Client(string host, int port ) throw new FileNotFoundException(); } - var data = new (string name, bool isDir)[size]; + var data = new List<(string, bool)>(); + + for (int i = 1; i < infoArray.Length; i += 2) { var isDir = Convert.ToBoolean(infoArray[i + 1]); - data[(i - 1) / 2] = (infoArray[i], isDir); + data.Add((infoArray[i], isDir)); } - return data; + return data.ToArray(); } /// diff --git a/MyFTP/MyFTPClient/Program.cs b/MyFTP/MyFTPClient/Program.cs index 593b2c5..0c57810 100644 --- a/MyFTP/MyFTPClient/Program.cs +++ b/MyFTP/MyFTPClient/Program.cs @@ -11,13 +11,19 @@ public static async Task Main(string[] args) { var client = new Client(args[0], Convert.ToInt32(args[1])); var token = new CancellationToken(); - while (args[0] != "exit" || !token.IsCancellationRequested) + Console.WriteLine("1 - List — листинг файлов в директории на сервере\nНапример, 1 ./Test/Files\n"); + Console.WriteLine("2 - Get — скачивание файла с сервера\n2 ./Test/Files/file1.txt\n"); + Console.WriteLine("Введите !exit, чтобы остановить сервер\n"); + Console.WriteLine("Введите команду:"); + var request = Console.ReadLine().Split(' '); + while (request[0] != "!exit" || !token.IsCancellationRequested) { - if (args[0] == "1") + if (request[0] == "1" && request.Length == 2) { try { - var response = await client.List(args[1], token); + var response = await client.List(request[1], token); + Console.WriteLine(response.Length); foreach (var file in response) { Console.WriteLine($"{file.Item1} {file.Item2}"); @@ -25,24 +31,28 @@ public static async Task Main(string[] args) } catch (FileNotFoundException) { - Console.WriteLine("Ошибка!"); + Console.WriteLine("-1"); } } - - if (args[0] == "2") + else if (request[0] == "2" && request.Length == 2) { - using (var fstream = new FileStream(args[2], FileMode.OpenOrCreate)) + using var fstream = new FileStream(request[2], FileMode.OpenOrCreate); + try { - try - { - var response = client.Get(args[1], fstream, token); - } - catch (FileNotFoundException) - { - Console.WriteLine("Ошибка!"); - } + 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(' '); } } } \ No newline at end of file diff --git a/MyFTP/MyFTPServer/Program.cs b/MyFTP/MyFTPServer/Program.cs index b3f2c12..82349c7 100644 --- a/MyFTP/MyFTPServer/Program.cs +++ b/MyFTP/MyFTPServer/Program.cs @@ -7,16 +7,23 @@ 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])); - await server.StartServer(); + var serverStop = server.StartServer(); Console.WriteLine("Введите !exit, чтобы остановить сервер"); var command = ""; while (command != "!exit") { command = Console.ReadLine(); } + server.StopServer(); + await serverStop; } catch (ArgumentException) { diff --git a/MyFTP/MyFTPServer/Server.cs b/MyFTP/MyFTPServer/Server.cs index 11622d8..a09e26d 100644 --- a/MyFTP/MyFTPServer/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -30,7 +30,7 @@ public async Task StartServer() _listener.Start(); while (!_tokenSource.IsCancellationRequested) { - var client = await _listener.AcceptTcpClientAsync(); + using var client = await _listener.AcceptTcpClientAsync(); task.Add(Working(client)); } await Task.WhenAll(task); From e3361dfed999ab17cd2698c52f1359a461b72a2f Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 4 Apr 2022 03:49:29 +0300 Subject: [PATCH 17/17] fix test --- MyFTP/MyFTP.Test/MyFTPTest.cs | 2 +- MyFTP/MyFTPServer/Server.cs | 41 +++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/MyFTP/MyFTP.Test/MyFTPTest.cs b/MyFTP/MyFTP.Test/MyFTPTest.cs index a5eb1f7..e43be81 100644 --- a/MyFTP/MyFTP.Test/MyFTPTest.cs +++ b/MyFTP/MyFTP.Test/MyFTPTest.cs @@ -41,7 +41,7 @@ public void GetInvalidFileNameTest() [Test] public void ListInvalidFileNameTest() { - Assert.ThrowsAsync(() => _client.Get("Text.txt", _fileStream, _cancellationToken)); + Assert.ThrowsAsync(() => _client.Get("Text.txt", _fileStream, _cancellationToken)); } [Test] diff --git a/MyFTP/MyFTPServer/Server.cs b/MyFTP/MyFTPServer/Server.cs index a09e26d..8a70355 100644 --- a/MyFTP/MyFTPServer/Server.cs +++ b/MyFTP/MyFTPServer/Server.cs @@ -30,7 +30,7 @@ public async Task StartServer() _listener.Start(); while (!_tokenSource.IsCancellationRequested) { - using var client = await _listener.AcceptTcpClientAsync(); + var client = await _listener.AcceptTcpClientAsync(); task.Add(Working(client)); } await Task.WhenAll(task); @@ -48,25 +48,28 @@ public void StopServer() /// private async Task Working(TcpClient client) { - using var stream = client.GetStream(); - using var reader = new StreamReader(stream); - using var writer = new StreamWriter(stream); - var request = await reader.ReadLineAsync(); - var (command, path) = (request?.Split()[0], request?.Split()[1]); - switch (command) + using (client) { - case "1": - await List(writer, path); - break; - case "2": - await Get(writer, path, stream); - break; - case "!exit": - StopServer(); - break; - default: - await writer.WriteAsync("Ваш протокол сломан!"); - break; + using var stream = client.GetStream(); + using var reader = new StreamReader(stream); + using var writer = new StreamWriter(stream); + var request = await reader.ReadLineAsync(); + var (command, path) = (request?.Split()[0], request?.Split()[1]); + switch (command) + { + case "1": + await List(writer, path); + break; + case "2": + await Get(writer, path, stream); + break; + case "!exit": + StopServer(); + break; + default: + await writer.WriteAsync("Ваш протокол сломан!"); + break; + } } }