How to implement an asynchronous socket in C#
By FoxLearn 1/13/2025 2:33:04 AM 83
It facilitates inter-process communication (IPC) by enabling data exchange. Once a connection is established between the server and client processes, they can use the socket to communicate and transfer data.
Purpose of Asynchronous Sockets
Asynchronous programming allows tasks to run without interrupting the flow or responsiveness of your application, enhancing both performance and user experience. While synchronous sockets are an option, they don't scale well because they block the thread. In contrast, asynchronous sockets enable resource-intensive I/O operations to run without blocking the main or executing thread, improving efficiency.
Create an asynchronous TCP socket in C#
To implement a TCP client-server communication, you'll typically set up a server process that listens on a specific port and a client process that can connect to the server from any available port. The server listens for incoming connection requests on its assigned port, while the client sends a connection request to the server's IP and port.
For example, how to set up a TCP server socket at a specified port:
IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = ipHostEntry.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 9000); TcpListener serverSocket = new TcpListener(ipEndPoint); serverSocket.Start();
Now, let’s create a class SocketServer
to handle asynchronous server socket operations. This class will include logic to create and start a TCP socket and await incoming client connections.
C# TcpListener async example
public class SocketServer { private static TcpListener serverSocket; public async void StartServer() { IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = ipHostEntry.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 9000); while (true) { serverSocket = new TcpListener(ipEndPoint); serverSocket.Start(); Console.WriteLine("Server started... awaiting connections..."); try { var tcpClient = await serverSocket.AcceptTcpClientAsync(); HandleConnectionAsync(tcpClient); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } private async void HandleConnectionAsync(TcpClient tcpClient) { // Write code to handle incoming client connections } }
Now, let’s improve the efficiency by eliminating the while-loop in the StartServer
method and using an asynchronous model for better performance:
public class SocketServer { private static TcpListener serverSocket; public static void StartServer() { IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = ipHostEntry.AddressList[0]; IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 9000); serverSocket = new TcpListener(ipEndPoint); serverSocket.Start(); Console.WriteLine("Asynchronous server listening on: " + ipEndPoint.Address.ToString()); WaitForClients(); } private static void WaitForClients() { serverSocket.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), null); } private static void OnClientConnected(IAsyncResult asyncResult) { try { TcpClient clientSocket = serverSocket.EndAcceptTcpClient(asyncResult); if (clientSocket != null) Console.WriteLine("Received connection from: " + clientSocket.Client.RemoteEndPoint.ToString()); HandleClientRequest(clientSocket); } catch { throw; } WaitForClients(); } private static void HandleClientRequest(TcpClient clientSocket) { // Code to process client requests } }
To start the server, call the StartServer
method in the Main
method:
static void Main(string[] args) { SocketServer.StartServer(); Console.Read(); }
Creating an Asynchronous TCP Client
The client needs a socket that connects to the server and exchanges data.
Here’s an example of an asynchronous client socket implementation:
public class SocketClient { 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 to send data } public void Close() { clientSocket.Close(); } public string Receive() { // Write code to receive data from the server } }
To connect to the server and send data, use the following code:
static void Main(string[] args) { SocketClient client = new SocketClient(); client.Connect("127.0.0.1", 9000); client.Send("Hello"); Console.Read(); }
This setup establishes a server that asynchronously handles client connections and a client that connects to the server and sends messages. You can expand the Send
and Receive
methods to handle the actual data exchange.
- How to retrieve the Executable Path in C#
- Dictionary with multiple values per key in C#
- How to Convert string to JSON in C#
- How to take a screenshot with Selenium WebDriver
- Sending JSON in .NET Core
- Writing Files Asynchronously with Multiple Threads in .NET Core
- Manipulating XML Google Merchant Data with C# and LINQ
- Set Local Folder for .NET Core in C#