diff --git a/Test2/Test2/Test2.sln b/Test2/Test2/Test2.sln new file mode 100644 index 0000000..17da8be --- /dev/null +++ b/Test2/Test2/Test2.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32505.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2", "Test2\Test2.csproj", "{9C443126-FE1B-4B5D-9622-95C543247946}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test2Tests", "Test2Tests\Test2Tests.csproj", "{95155417-93B4-470F-99AE-4B89430F2E53}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9C443126-FE1B-4B5D-9622-95C543247946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C443126-FE1B-4B5D-9622-95C543247946}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C443126-FE1B-4B5D-9622-95C543247946}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C443126-FE1B-4B5D-9622-95C543247946}.Release|Any CPU.Build.0 = Release|Any CPU + {95155417-93B4-470F-99AE-4B89430F2E53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95155417-93B4-470F-99AE-4B89430F2E53}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95155417-93B4-470F-99AE-4B89430F2E53}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95155417-93B4-470F-99AE-4B89430F2E53}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CF03D00E-ED5D-4B68-949C-102697743BA1} + EndGlobalSection +EndGlobal diff --git a/Test2/Test2/Test2/Client.cs b/Test2/Test2/Test2/Client.cs new file mode 100644 index 0000000..b4d6021 --- /dev/null +++ b/Test2/Test2/Test2/Client.cs @@ -0,0 +1,86 @@ +namespace Server; + +using System.Net.Sockets; +using System.Net; + +/// +/// Сlass representing the client +/// +public class Client +{ + private readonly int port; + private readonly IPAddress address; + + private readonly CancellationTokenSource source = new(); + + public CancellationTokenSource GetSource => source; + + /// + /// Сonstructor + /// + /// ip adress + /// port + public Client(IPAddress adress, int port) + { + this.port = port; + this.address = adress; + } + + // Принять сообщение + private async Task GetMessage(NetworkStream stream) { + using var streamReader = new StreamReader(stream); + var data = (await streamReader.ReadLineAsync()); + while (data != "exit") { + Console.WriteLine($"{data}"); + data = (await streamReader.ReadLineAsync()); + + if (source.IsCancellationRequested) + { + break; + } + } + + source.Cancel(); + } + + // Отправить сообщение + private async Task SendMessage(NetworkStream stream) + { + using var streamWriter = new StreamWriter(stream) { AutoFlush = true}; + var data = Console.ReadLine(); + while (data != "exit") + { + await streamWriter.WriteLineAsync($"{data}"); + + if (source.IsCancellationRequested) + { + break; + } + } + + source.Cancel(); + } + + /// + /// Запуск клиентской части + /// + public async void Start() { + var client = new TcpClient(); + // Подключаемся к узлу + await client.ConnectAsync(address, port); + + while (!source.Token.IsCancellationRequested) + { + // Получаем поток для записи и чтения + using var stream = client.GetStream(); + Task a = Task.Run(() => SendMessage(stream)); + Task b = Task.Run(() => GetMessage(stream)); + if (source.IsCancellationRequested) + { + break; + } + } + + client.Close(); + } +} diff --git a/Test2/Test2/Test2/Program.cs b/Test2/Test2/Test2/Program.cs new file mode 100644 index 0000000..9a26b37 --- /dev/null +++ b/Test2/Test2/Test2/Program.cs @@ -0,0 +1,34 @@ +using System.Net; + +if (args.Length > 2 || args.Length <= 0) +{ + return; +} + +if (!int.TryParse(args[0], out int port)) +{ + Console.WriteLine("incorrect port input"); + return; +} + +if (port < 1024 || port > 65535) +{ + Console.WriteLine("incorrect port input"); + return; +} + +if (args.Length == 1) { + var server = new Server.Server(port); + await Task.Run(() => server.Start()); +} +else { + + if (!IPAddress.TryParse(args[1], out IPAddress? ip)) + { + Console.WriteLine("incorrect ip address input"); + return; + } + + var client = new Server.Client(ip!, port); + await Task.Run(() => client.Start()); +} \ No newline at end of file diff --git a/Test2/Test2/Test2/Server.cs b/Test2/Test2/Test2/Server.cs new file mode 100644 index 0000000..72d447b --- /dev/null +++ b/Test2/Test2/Test2/Server.cs @@ -0,0 +1,89 @@ +namespace Server; + +using System.Net.Sockets; +using System.Net; + +/// +/// Class representing the server +/// +public class Server +{ + private readonly int port; + + private readonly CancellationTokenSource source = new(); + + public CancellationTokenSource GetSource => source ; + + /// + /// Сonstructor + /// + /// port + public Server(int port) + { + this.port = port; + } + + /// + /// Function to start the server (it will start listening for connections from clients) + /// + /// + public async Task Start() + { + var tcpListener = new TcpListener(IPAddress.Any, port); + + // Слушаем порт + tcpListener.Start(); + + while (!source.Token.IsCancellationRequested) + { + // Блокируем поток до установления соединения + var acceptedSocket = await tcpListener.AcceptSocketAsync(); + // Поток для записи и чтения в полученный сокет + using var newtworkStream = new NetworkStream(acceptedSocket); + Task a = Task.Run(() => SendMessage(newtworkStream)); + Task b = Task.Run(() => GetMessage(newtworkStream)); + if (source.IsCancellationRequested) { + acceptedSocket.Close(); + break; + } + } + + tcpListener.Stop(); + } + + // Принять сообщение + private async Task GetMessage(NetworkStream stream) + { + using var streamReader = new StreamReader(stream); + var data = (await streamReader.ReadLineAsync()); + while (data != "exit") + { + Console.WriteLine($"{data}"); + data = (await streamReader.ReadLineAsync()); + + if (source.IsCancellationRequested) + { + break; + } + } + + source.Cancel(); + } + + // Отправить сообщение + private async Task SendMessage(NetworkStream stream) + { + using var streamWriter = new StreamWriter(stream) { AutoFlush = true }; + var data = Console.ReadLine(); + while (data != "exit") + { + await streamWriter.WriteLineAsync($"{data}"); + + if (source.IsCancellationRequested) { + break; + } + } + + source.Cancel(); + } +} \ No newline at end of file diff --git a/Test2/Test2/Test2/Test2.csproj b/Test2/Test2/Test2/Test2.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/Test2/Test2/Test2/Test2.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/Test2/Test2/Test2Tests/Test2Tests.cs b/Test2/Test2/Test2Tests/Test2Tests.cs new file mode 100644 index 0000000..53927b8 --- /dev/null +++ b/Test2/Test2/Test2Tests/Test2Tests.cs @@ -0,0 +1,23 @@ +namespace Test2Tests; + +using Server; +using System.Net; + +public class Tests2Tests +{ + Server? server; + CancellationTokenSource cancelTokenSource = new(); + + [SetUp] + public void Setup() + { + var server = new Server(10000); + server.Start(); + } + + [Test] + public void Test1() + { + + } +} \ No newline at end of file diff --git a/Test2/Test2/Test2Tests/Test2Tests.csproj b/Test2/Test2/Test2Tests/Test2Tests.csproj new file mode 100644 index 0000000..ceadffd --- /dev/null +++ b/Test2/Test2/Test2Tests/Test2Tests.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + + diff --git a/Test2/Test2/Test2Tests/Usings.cs b/Test2/Test2/Test2Tests/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/Test2/Test2/Test2Tests/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file