From 8c953be3e3113b1362eea7ebff08add2a324e5fd Mon Sep 17 00:00:00 2001 From: syneffort Date: Tue, 7 Feb 2023 11:28:25 +0900 Subject: [PATCH] eap (event-based asynchronous pattern) --- EAP/Client/Client.cs | 61 +++++++++++++++++++++++++++++++ EAP/Client/Client.csproj | 10 ++++++ EAP/EAP.sln | 31 ++++++++++++++++ EAP/EAP/EAP.csproj | 10 ++++++ EAP/EAP/Program.cs | 10 ++++++ EAP/Server/Server.cs | 77 ++++++++++++++++++++++++++++++++++++++++ EAP/Server/Server.csproj | 10 ++++++ 7 files changed, 209 insertions(+) create mode 100644 EAP/Client/Client.cs create mode 100644 EAP/Client/Client.csproj create mode 100644 EAP/EAP.sln create mode 100644 EAP/EAP/EAP.csproj create mode 100644 EAP/EAP/Program.cs create mode 100644 EAP/Server/Server.cs create mode 100644 EAP/Server/Server.csproj diff --git a/EAP/Client/Client.cs b/EAP/Client/Client.cs new file mode 100644 index 0000000..45a29cd --- /dev/null +++ b/EAP/Client/Client.cs @@ -0,0 +1,61 @@ +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace Client; + +internal class Client +{ + static void Main(string[] args) + { + Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 20000); + + SocketAsyncEventArgs arg = new SocketAsyncEventArgs(); + arg.RemoteEndPoint = endPoint; + arg.Completed += ConnectCompleted; + bool pending = socket.ConnectAsync(arg); + if (!pending) + ConnectCompleted(socket, arg); + + while (true) + { + Thread.Sleep(1000); + } + } + + private static void ConnectCompleted(object? sender, SocketAsyncEventArgs e) + { + if (sender == null || e == null) + return; + + Socket socket = (Socket)sender; + e.Dispose(); + + string str = Console.ReadLine() ?? string.Empty; + byte[] buffer = Encoding.UTF8.GetBytes(str); + + SocketAsyncEventArgs arg = new SocketAsyncEventArgs(); + arg.SetBuffer(buffer, 0, buffer.Length); + arg.Completed += SendCompleted; + bool pending = socket.SendAsync(arg); + if (!pending) + SendCompleted(socket, arg); + } + + private static void SendCompleted(object? sender, SocketAsyncEventArgs e) + { + if (sender == null || e == null) + return; + + Socket socket = (Socket)sender; + + string str = Console.ReadLine() ?? string.Empty; + byte[] buffer = Encoding.UTF8.GetBytes(str); + + e.SetBuffer(buffer, 0, buffer.Length); + bool pending = socket.SendAsync(e); + if (!pending) + SendCompleted(socket, e); + } +} \ No newline at end of file diff --git a/EAP/Client/Client.csproj b/EAP/Client/Client.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/EAP/Client/Client.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/EAP/EAP.sln b/EAP/EAP.sln new file mode 100644 index 0000000..5f2433b --- /dev/null +++ b/EAP/EAP.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{8423FCCE-2410-4B71-8760-DB9BF462CD6F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{BAA1EE6E-A707-4BAB-A179-15F48C92FD01}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8423FCCE-2410-4B71-8760-DB9BF462CD6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8423FCCE-2410-4B71-8760-DB9BF462CD6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8423FCCE-2410-4B71-8760-DB9BF462CD6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8423FCCE-2410-4B71-8760-DB9BF462CD6F}.Release|Any CPU.Build.0 = Release|Any CPU + {BAA1EE6E-A707-4BAB-A179-15F48C92FD01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BAA1EE6E-A707-4BAB-A179-15F48C92FD01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BAA1EE6E-A707-4BAB-A179-15F48C92FD01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BAA1EE6E-A707-4BAB-A179-15F48C92FD01}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {814AD39F-59E2-4A4E-A7E0-3AEA0921C2F1} + EndGlobalSection +EndGlobal diff --git a/EAP/EAP/EAP.csproj b/EAP/EAP/EAP.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/EAP/EAP/EAP.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/EAP/EAP/Program.cs b/EAP/EAP/Program.cs new file mode 100644 index 0000000..4b565ff --- /dev/null +++ b/EAP/EAP/Program.cs @@ -0,0 +1,10 @@ +namespace EAP +{ + internal class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello, World!"); + } + } +} \ No newline at end of file diff --git a/EAP/Server/Server.cs b/EAP/Server/Server.cs new file mode 100644 index 0000000..370bb82 --- /dev/null +++ b/EAP/Server/Server.cs @@ -0,0 +1,77 @@ +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace Server; + +internal class Server +{ + private static readonly int BUFFER_SIZE = 256; + + static void Main(string[] args) + { + Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 20000); + serverSocket.Bind(endPoint); + serverSocket.Listen(100); + + SocketAsyncEventArgs arg = new SocketAsyncEventArgs(); + arg.Completed += AcceptCompleted; + bool pending = serverSocket.AcceptAsync(arg); + if (!pending) + AcceptCompleted(serverSocket, arg); + + while (true) + { + Thread.Sleep(1000); + } + } + + private static void AcceptCompleted(object? sender, SocketAsyncEventArgs e) + { + if (sender == null || e == null || e.AcceptSocket == null) + return; + + Socket serverSocket = (Socket)sender; + Socket clientSocket = e.AcceptSocket; + Console.WriteLine(clientSocket.RemoteEndPoint); + + e.AcceptSocket = null; + bool pending = serverSocket.AcceptAsync(e); + if (!pending) + AcceptCompleted(serverSocket, e); + + SocketAsyncEventArgs arg = new SocketAsyncEventArgs(); + arg.Completed += ReceiveCompleted; + byte[] buffer = new byte[BUFFER_SIZE]; + arg.SetBuffer(buffer, 0, buffer.Length); + + bool pending2 = clientSocket.ReceiveAsync(arg); + if (!pending2) + ReceiveCompleted(clientSocket, arg); + } + + private static void ReceiveCompleted(object? sender, SocketAsyncEventArgs e) + { + if (sender == null || e == null) + return; + + Socket clientSocket = (Socket)sender; + if (e.BytesTransferred < 1) + { + Console.WriteLine("Client is disconnected..."); + clientSocket.Dispose(); + e.Dispose(); + return; + } + + Console.WriteLine(Encoding.UTF8.GetString(e.Buffer)); + + byte[] buffer = new byte[BUFFER_SIZE]; + e.SetBuffer(buffer, 0, buffer.Length); + + bool pending = clientSocket.ReceiveAsync(e); + if (!pending) + ReceiveCompleted(clientSocket, e); + } +} \ No newline at end of file diff --git a/EAP/Server/Server.csproj b/EAP/Server/Server.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/EAP/Server/Server.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + +