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