You can increase the performance and scalability of your client-server applications by using asynchronous sockets. Here’s how. Credit: af_studio / Getty Images A socket is defined as the endpoint of a two-way communication between two processes running over a network. Inter-process communication can be achieved using sockets. After a connection between the server and client, i.e., after the server process and the client process are established, they can communicate for the purpose of exchanging data using sockets. Why do we need asynchronous sockets? Asynchronous programming enables you to execute tasks without the need to pause the execution flow or responsiveness of your application. This in turn helps to improve the performance and responsiveness of your application. You can also build synchronous sockets, but such sockets don’t scale well since they block your thread. Asynchrony can perform resource-intensive I/O operations without the need to block the main or the executing thread of your application. Create an asynchronous TCP socket in C# To implement a TCP client-server socket communication, you would typically need to create a server process that should start at a particular port and also a client process that can start on any port and send a connection request to the server. The server process listens for incoming connection requests at the port on which it has been started. The following code snippet illustrates how you can create a TCP socket and start it at a particular port. IPHostEntry ipHostEntry = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostEntry.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8888); TcpListener serverSocket = new TcpListener(ipEndPoint); serverSocket.Start(); Let’s now create a class named ServerSocket that represents the asynchronous server socket class. This class would wrap the logic to create and start a TCP socket and also wait for incoming client connections. public class SocketServer { private static TcpListener serverSocket; public async void StartServer() { IPHostEntry ipHostEntry = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostEntry.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8888); while (true) { serverSocket = new TcpListener(ipEndPoint); serverSocket.Start(); Console.WriteLine("Server Socket started...waiting for connections..."); try { var tcpClient = await serverSocket.AcceptTcpClientAsync(); HandleConnectionAsync(tcpClient); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } } The HandleConnectionAsync will be used to process the individual clients. private async void HandleConnectionAsync(TcpClient tcpClient) { //Write code here to process the incoming client connections } Let’s now modify the code of the StartServer method to eliminate the looping. We can use an async model in lieu of looping for greater efficiency and improved performance. public class SocketServer { private static TcpListener serverSocket; public static void StartServer() { IPHostEntry ipHostEntry = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostEntry.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8888); serverSocket = new TcpListener(ipEndPoint); serverSocket.Start(); Console.WriteLine("Asynchonous server socket is listening at: " + ipEndPoint.Address.ToString()); WaitForClients(); } } Refer to the ServerSocket class shown above. The static method StartServer of the ServerSocket class contains the necessary code to create a socket and start it. It also waits for incoming client connections sans the need of looping. Note the call to the WaitForClients method in the last statement of the StartServer method. The WaitForClients() method is shown below. private static void WaitForClients() { serverSocket.BeginAcceptTcpClient(new System.AsyncCallback(OnClientConnected), null); } The BeginAcceptTcpClient method has been used to asynchronously accept client connections. It should be noted that the BeginAcceptTcpClient operation must be completed by invoking the EndAcceptTcpClient method on the socket instance. The OnClientConnected callback method is shown below. private static void OnClientConnected(IAsyncResult asyncResult) { try { TcpClient clientSocket = serverSocket.EndAcceptTcpClient(asyncResult); if (clientSocket != null) Console.WriteLine("Received connection request from: " + clientSocket.Client.RemoteEndPoint.ToString()); HandleClientRequest(clientSocket); } catch { throw; } WaitForClients(); } Here is the signature of the HandleClientRequest method that does the actual processing of incoming client requests. private static void HandleClientRequest(TcpClient clientSocket) { //Write your code here to process the data } And the following code snippet shows how you can start the server socket. static void Main(string[] args) { SocketServer.StartServer(); Console.Read(); } Create an asynchronous TCP client socket in C# At the client side, you will need to run a client socket that connects to the server socket and sends and receives data to and from the server. The following class named IDGSocketClient represents our asynchronous client socket. public class IDGSocketClient { System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); NetworkStream networkStream; public void Connect(string ipAddress, int port) { clientSocket.Connect(ipAddress, port); } public void Send(string data) { //Write code here to send data } public void Close() { clientSocket.Close(); } public string Receive() { //Write code here to receive data from the server } } The following code snippet illustrates how you can connect to the server socket from the client and send data. static void Main(string[] args) { IDGSocketClient client = new IDGSocketClient(); client.Connect("127.0.0.1",8888); client.Send("Hello"); Console.Read(); } The end. Related content news Wasmer WebAssembly platform now backs iOS Wasmer 5.0 release also features improved performance, a leaner codebase, and discontinued support for the Emscripten toolchain. By Paul Krill Oct 30, 2024 2 mins Mobile Development Web Development Software Development news analysis What Entrust certificate distrust means for developers Secure communications between web browsers and web servers depend on digital certificates backed by certificate authorities. What if the web browsers stop trusting your CA? By Travis Van Oct 30, 2024 9 mins Browser Security Web Development Application Security news Next.js 15 arrives with faster bundler High-performance Rust-based Turbopack bundler moves from beta to stable with the latest update of the React-based web framework. By Paul Krill Oct 24, 2024 2 mins JavaScript React Web Development feature WasmGC and the future of front-end Java development WebAssembly’s garbage collection extension makes it easier to run languages like Java on the front end. Could it be the start of a new era in web development? By Matthew Tyson Oct 16, 2024 10 mins Web Development Software Development Resources Videos