/// <summary> Main rx loop which waits for commands and then issues them to anyone listening.</summary>
        internal virtual void  listenForMessages()
        {
            DProtocolNotifierIF[] listeners = new DProtocolNotifierIF[0];

            while (!m_stopRx)
            {
                /* read the data */
                try
                {
                    DMessage msg = rxMessage();

                    /* Now traverse our list of interested parties and let them deal with the message */
                    listeners = (DProtocolNotifierIF[])m_listeners.ToArray(typeof(DProtocolNotifierIF)); // copy the array to avoid multithreading problems
                    for (int i = 0; i < listeners.Length; ++i)
                    {
                        DProtocolNotifierIF elem = listeners[i];
                        try
                        {
                            elem.messageArrived(msg, this);
                        }
                        catch (Exception exc)
                        /* catch unchecked exceptions */
                        {
                            if (Trace.error)
                            {
                                Console.Error.WriteLine("Error in listener parsing incoming message :"); //$NON-NLS-1$
                                Console.Error.WriteLine(msg.inToString(16));
                                Console.Error.Write(exc.StackTrace);
                                Console.Error.Flush();
                            }
                        }
                        msg.reset(); /* allow others to reparse the message */
                    }

                    /* now dispose with the message */
                    DMessageCache.free(msg);
                }
                //catch (IOException e)
                //{
                //    // this is a healthy exception that we simply ignore, since it means we haven't seen
                //    // data for a while; is all.
                //}
                finally
                {
                }
            }
        }
        /// <summary> Get the next message on the input stream, using the context contained within
        /// the message itself to demark its end
        /// </summary>
        private DMessage rxMessage()
        {
            long size    = readDWord();
            long command = readDWord();

            //System.out.println("rxMessage: " + DMessage.inTypeName(command) + " size=" + size);

            if (size < 0 || command < 0)
            {
                throw new IOException("socket closed");                 //$NON-NLS-1$
            }

            /*
             * Ask our message cache for a message
             */
            DMessage message = DMessageCache.alloc((int)size);

            byte[] messageContent = message.Data;
            int    offset         = 0;

            /* block until we get the entire message, which may come in pieces */
            while (offset < size)
            {
                int count = m_in.Read(messageContent, offset, (int)size - offset);
                //m_ReceivedLog.Add(messageContent, offset, count);
                offset += count;
            }

            /* now we have the data of the message, set its type and we are done */
            message.Type = (int)command;
            lock (this)
            {
                m_msgRx++;
            }
            return(message);
        }