Asynchronous Server Socket Example
.NET Framework 1.1
The following example program creates a server that receives connection requests from clients. The server is built with an asynchronous socket, so execution of the server application is not suspended while it waits for a connection from a client. The application receives a string from the client, displays the string on the console, and then echoes the string back to the client. The string from the client must contain the string "<EOF>" to signal the end of the message.
Imports System Imports System.Net Imports System.Net.Sockets Imports System.Text Imports System.Threading ' State object for reading client data asynchronously Public Class StateObject ' Client socket. Public workSocket As Socket = Nothing ' Size of receive buffer. Public Const BufferSize As Integer = 1024 ' Receive buffer. Public buffer(BufferSize) As Byte ' Received data string. Public sb As New StringBuilder() End Class 'StateObject Public Class AsynchronousSocketListener ' Incoming data from the client. Public Shared data As String = Nothing ' Thread signal. Public Shared allDone As New ManualResetEvent(False) Public Sub New() End Sub 'New Public Shared Sub StartListening() ' Data buffer for incoming data. Dim bytes() As Byte = New [Byte](1024) {} ' Establish the local endpoint for the socket. ' The DNS name of the computer ' running the listener is "host.contoso.com". Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName()) Dim ipAddress As IPAddress = ipHostInfo.AddressList(0) Dim localEndPoint As New IPEndPoint(ipAddress, 11000) ' Intializes a TCP/IP socket. Dim listener As New Socket(AddressFamily.InterNetwork, _ SocketType.Stream, ProtocolType.Tcp) ' Bind the socket to the local endpoint and listen for incoming ' connections. Try listener.Bind(localEndPoint) listener.Listen(100) While True ' Set the event to nonsignaled state. allDone.Reset() ' Start an asynchronous socket to listen for connections. Console.WriteLine("Waiting for a connection...") listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), _ listener) ' Wait until a connection is made before continuing. allDone.WaitOne() End While Catch e As Exception Console.WriteLine(e.ToString()) End Try Console.WriteLine(ControlChars.Cr + "Press ENTER to continue...") Console.Read() End Sub 'StartListening Public Shared Sub AcceptCallback(ar As IAsyncResult) ' Signal the main thread to continue. allDone.Set() ' Get the socket that handles the client request. Dim listener As Socket = CType(ar.AsyncState, Socket) Dim handler As Socket = listener.EndAccept(ar) ' Create the state object. Dim state As New StateObject() state.workSocket = handler handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, _ New AsyncCallback(AddressOf ReadCallback), state) End Sub 'AcceptCallback Public Shared Sub ReadCallback(ar As IAsyncResult) Dim content As [String] = [String].Empty ' Retrieve the state object and the handler socket ' from the asynchronous state object. Dim state As StateObject = CType(ar.AsyncState, StateObject) Dim handler As Socket = state.workSocket ' Read data from client socket. Dim bytesRead As Integer = handler.EndReceive(ar) If bytesRead > 0 Then ' There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, _ bytesRead)) ' Check for end-of-file tag. If it is not there, read ' more data. content = state.sb.ToString() If content.IndexOf("<EOF>") > - 1 Then ' All the data has been read from the ' client. Display it on the console. Console.WriteLine("Read {0} bytes from socket. " + _ ControlChars.Cr + " Data : {1}", content.Length, content) ' Echo the data back to the client. Send(handler, content) Else ' Not all data received. Get more. handler.BeginReceive(state.buffer, 0,StateObject.BufferSize, _ 0, New AsyncCallback(AddressOf ReadCallback), state) End If End If End Sub 'ReadCallback Private Shared Sub Send(handler As Socket, data As [String]) ' Convert the string data to byte data using ASCII encoding. Dim byteData As Byte() = Encoding.ASCII.GetBytes(data) ' Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, _ New AsyncCallback(AddressOf SendCallback), handler) End Sub 'Send Private Shared Sub SendCallback(ar As IAsyncResult) Try ' Retrieve the socket from the state object. Dim handler As Socket = CType(ar.AsyncState, Socket) ' Complete sending the data to the remote device. Dim bytesSent As Integer = handler.EndSend(ar) Console.WriteLine("Sent {0} bytes to client.", bytesSent) handler.Shutdown(SocketShutdown.Both) handler.Close() Catch e As Exception Console.WriteLine(e.ToString()) End Try End Sub 'SendCallback 'Entry point that delegates to C-style main Private Function. Public Overloads Shared Sub Main() System.Environment.ExitCode = _ Main(System.Environment.GetCommandLineArgs()) End Sub Overloads Public Shared Function Main(args() As [String]) As Integer StartListening() Return 0 End Function 'Main End Class 'AsynchronousSocketListener [C#] using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; // State object for reading client data asynchronously public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 1024; // Receive buffer. public byte[] buffer = new byte[BufferSize]; // Received data string. public StringBuilder sb = new StringBuilder(); } public class AsynchronousSocketListener { // Incoming data from client. public static string data = null; // Thread signal. public static ManualResetEvent allDone = new ManualResetEvent(false); public AsynchronousSocketListener() { } public static void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024]; // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); // Bind the socket to the local endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(100); while (true) { // Set the event to nonsignaled state. allDone.Reset(); // Start an asynchronous socket to listen for connections. Console.WriteLine("Waiting for a connection..."); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener ); // Wait until a connection is made before continuing. allDone.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("\nPress ENTER to continue..."); Console.Read(); } public static void AcceptCallback(IAsyncResult ar) { // Signal the main thread to continue. allDone.Set(); // Get the socket that handles the client request. Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object. StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } public static void ReadCallback(IAsyncResult ar) { String content = String.Empty; // Retrieve the state object and the handler socket // from the asynchronous state object. StateObject state = (StateObject) ar.AsyncState; Socket handler = state.workSocket; // Read data from the client socket. int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { // There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString( state.buffer,0,bytesRead)); // Check for end-of-file tag. If it is not there, read // more data. content = state.sb.ToString(); if (content.IndexOf("<EOF>") > -1) { // All the data has been read from the // client. Display it on the console. Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content ); // Echo the data back to the client. Send(handler, content); } else { // Not all data received. Get more. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } } private static void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } private static void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket handler = (Socket) ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); Console.WriteLine("Sent {0} bytes to client.", bytesSent); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static int Main(String[] args) { StartListening(); return 0; } }
See Also
Asynchronous Client Socket Example | Using an Asynchronous Server Socket | Socket Code Examples