/// <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); }