/// <summary>
 /// When a message is received on the specified UDP Multicast address/port.
 /// </summary>
 /// <remarks>
 /// Assumed to be not running under a thread safe context. As long as we don's access
 /// the socket referenced in the <see cref="MessageRequest"/> class we should be ok.
 /// <para></para>
 /// The buffer element is fine to access as it is created per call, regardless of which
 /// thread context has entered the ProcessMessage() method.
 /// </remarks>
 /// <param name="receivedByteCount">
 /// The number of bytes available to read.
 /// </param>
 /// <param name="state">
 /// The buffer state. 
 /// </param>
 private void OnMessageReceived(int receivedByteCount, MessageRequest state)
 {
     if (receivedByteCount > 0)
     {
         try
         {
             state.Execute();
         }
         catch (Exception ex)
         {
             m_Logger.Error("Exception detected handling message.", ex);
         }
     }
 }
        /// <summary>
        /// When a message is received on the specified UDP Multicast address/port.
        /// </summary>
        /// <remarks>
        /// Assumed to run under a thread-safe context.
        /// </remarks>
        /// <param name="receivedByteCount">
        /// The number of bytes available to read.
        /// </param>
        /// <param name="state">
        /// The buffer state. 
        /// </param>
        private void OnMessageReceived(int receivedByteCount, MessageRequest state)
        {
            if (receivedByteCount > 0)
            {
                // Copy message buffer and send it the message handler.
                var message = new byte[receivedByteCount];
                Array.Copy(state.Buffer, message, receivedByteCount);

                m_MessageHandler.HandleMessage(ref message);
            }
        }
        /// <summary>
        /// Checks to see if there is any data on the socket to process.
        /// </summary>
        /// <remarks>
        /// Will not block indefinitely while waiting for data or throwing 
        /// an exception if a timeout was specified on the read.
        /// </remarks>
        public void ProcessMessage()
        {
            MessageRequest messageRequest = null;
            int bytesRead = 0;

            var logger = new ConsoleLogger();

            lock (m_SyncLock)
            {
                //logger.LogFreeMemory();

                if (!m_IsOpen) Open();
                if (m_IsOpen)
                {
                    logger.LogFreeMemory();

                    messageRequest = new MessageRequest(m_MessageHandler, BufferSizeInBytes);

                    try
                    {
                        bool hasPayload = m_Client.Poll(PeekTimeoutInMilliseconds, SelectMode.SelectRead);
                        if (hasPayload)
                        {
                            bytesRead = m_Client.Receive(messageRequest.Buffer, 0, messageRequest.Buffer.Length, SocketFlags.None);
                        }
                    }
                    catch (Exception ex)
                    {
                        m_Logger.Error("Exception occurred receiving data from UDP socket.", ex);
                        Close();
                    }
                }
            }

            if (bytesRead > 0)
            {
                OnMessageReceived(bytesRead, messageRequest);
            }

            if (messageRequest != null)
            {
                messageRequest.Dispose();
            }

            //logger.LogFreeMemory();
        }
        /// <summary>
        /// Checks to see if there is any data on the socket to process.
        /// </summary>
        /// <remarks>
        /// Will not block indefinitely while waiting for data or throwing 
        /// an exception if a timeout was specified on the read.
        /// </remarks>
        public void ListenForMessage()
        {
            lock (m_SyncLock)
            {
                bool hasPayload = m_Socket.Poll(PeekTimeoutInMilliseconds, SelectMode.SelectRead);
                if (hasPayload)
                {
                    var state = new MessageRequest(m_MessageHandler, BufferSizeInBytes);
                    EndPoint remoteendpoint = new IPEndPoint(IPAddress.Parse(m_HostName), m_Port);

                    int bytesRead = m_Socket.ReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref remoteendpoint);

                    this.OnMessageReceived(bytesRead, state);
                }
            }
        }