Mercurial > silverbladetech
view Messaging/Server/Listeners/AsyncSocketListener.cs @ 29:9919ee227c93
msmq added
author | adminsh@apollo |
---|---|
date | Wed, 21 Mar 2012 22:09:18 +0000 |
parents | 4c0dea4760c5 |
children |
line wrap: on
line source
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using Common.Messages; using GalaSoft.MvvmLight.Messaging; using Server.Interfaces; namespace Server.Listeners { public class AsyncSocketListener : IListener { public bool IsListening { get; set; } private readonly int _portNumber; // Thread signal. public static ManualResetEvent AllDone = new ManualResetEvent(false); public AsyncSocketListener(int portNumber) { IsListening = false; _portNumber = portNumber; } public void Start() { if (IsListening) { Messenger.Default.Send(new SocketLogMessage() { Body = "Already listening..." }); return; } Messenger.Default.Send(new SocketLogMessage() { Body = "Opening listener..." }); // Data buffer for incoming data. var bytes = new Byte[1024]; // Establish the local endpoint for the socket var ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); var ipAddress = ipHostInfo.AddressList[2]; var localEndPoint = new IPEndPoint(ipAddress, _portNumber); // Create a TCP/IP socket. using(var 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); IsListening = true; Messenger.Default.Send(new SocketLogMessage() { Body = "Listener opened" }); while (IsListening) { // Set the event to nonsignaled state. AllDone.Reset(); // Start an asynchronous socket to listen for connections. Messenger.Default.Send(new SocketLogMessage() { Body = "Waiting for a connection..." }); listener.BeginAccept( AcceptCallback, listener); // Wait until a connection is made before continuing. AllDone.WaitOne(); } if (listener.Connected) { Messenger.Default.Send(new SocketLogMessage() { Body = "Shutting down listener..." }); listener.Shutdown(SocketShutdown.Both); Messenger.Default.Send(new SocketLogMessage() { Body = "Disconnecting listener..." }); listener.Disconnect(true); } } catch (Exception e) { Messenger.Default.Send(new SocketLogMessage() { Body = e.Message }); } finally { Messenger.Default.Send(new SocketLogMessage() { Body = "Connection closed." }); } } } public void AcceptCallback(IAsyncResult ar) { // Signal the main thread to continue. AllDone.Set(); // Get the socket that handles the client request. var listener = (Socket) ar.AsyncState; var handler = listener.EndAccept(ar); // Create the state object. var state = new StateObject {WorkSocket = handler}; handler.BeginReceive( state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state); } public void ReadCallback(IAsyncResult ar) { var content = String.Empty; // Retrieve the state object and the handler socket // from the asynchronous state object. var state = (StateObject)ar.AsyncState; var handler = state.WorkSocket; // Read data from the client socket. var bytesRead = handler.EndReceive(ar); if (bytesRead <= 0) return; // 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. Messenger.Default.Send( new SocketLogMessage() { Body = string.Format( "Read {0} bytes from socket. \n Data : {1}", content.Length, content) }); // Echo the data back to the client. Send(handler, "The following message was received: " + content); } else { // Not all data received. Get more. handler.BeginReceive( state.Buffer, 0, StateObject.BufferSize, 0, ReadCallback, state); } } private void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. var byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend( byteData, 0, byteData.Length, 0, SendCallback, handler); } private void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. var handler = (Socket)ar.AsyncState; // Complete sending the data to the remote device. var bytesSent = handler.EndSend(ar); Messenger.Default.Send(new SocketLogMessage() { Body = string.Format("Sent {0} bytes to client.", bytesSent) }); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Messenger.Default.Send(new SocketLogMessage() { Body = e.Message }); } } public void Stop() { if (IsListening == false) return; Messenger.Default.Send(new SocketLogMessage() { Body = "Closing connection..." }); IsListening = false; AllDone.Set(); } } // State object for reading client data asynchronously public class StateObject { // Client socket. public Socket WorkSocket; // 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(); } }