From: Tom Anderson on 7 Oct 2009 17:06 On Wed, 7 Oct 2009, Mark wrote: > On Tue, 06 Oct 2009 10:24:59 -0700, Daniel Pitts > <newsgroup.spamfilter(a)virtualinfinity.net> wrote: > >> Mark wrote: >>> Is it possible to do a non-destructive read on a socket in Java? I >>> want the functionality similar to the C library recv() using the >>> MSG_PEEK flag. >>> >>> More information: >>> I am implementing an API in Java which needs to send a "are you alive" >>> application message over a socket. In reply it will get a "I am >>> alive" message. However there may be another type of message already >>> waiting which the API must not read. The presence of any message will >>> be enough for the API call to succeed. The "I am alive" message can >>> just be discarded if it is read later. >> >> Rather than either of those, why not use a message dispatcher that reads >> any available message, and dispatches it accordingly, including the "I >> am alive" message. > > The problem is that there may not be anything that can consume some > types of message at that time. The API is defined this way. > For example there are API methods defined, including: > > test() - Send a keepalive message and peek into the tcp/ip buffer to > see if there is a response. > get() - Read an application message (if present). > > If the consumer calls test() then there is nothing to handle an > application message. So you stick it in a queue. Next time someone calls get(), they get the message from the queue. Simple. tom -- Model 706-8073-421, Robot Sonic
From: Gilbert on 7 Oct 2009 18:48 Kevin McMurtrie wrote: > In article <c21mc51u8vktmemgdd5q4q80s41pqva879(a)4ax.com>, > > It doesn't sound like that's going to work reliably. Data existing and > data flowing aren't the same thing. I think what you need is a message > dispatcher thread, or demultiplexer if you want to call it that, > handling the stream. It will route heartbeats off to their handler and > app data off to another handler. Being that it operates independently > of app data streams, it will be able to identify exactly the last time > and type of data that passed through. That sounds like it could help with something I'm doing reading messages from a serial port. There are about 20 message types that require slightly different handling depending on the message identifier byte. I don't really want the message dispatcher to have to know about all the different handlers and the "standard" listener pattern means that all handlers receive all messages and ignore those that they don't want which seems wasteful. What I think I'd like to be able to do is to register a listener for a specific message id. Is there anything available that I could extend or would I have to roll my own Regards
From: EJP on 7 Oct 2009 19:27 Mark wrote: > I am using SocketChannel.read() and SocketChannel.write() > [non-blocking mode]. So therefore the answer to your question is a combination of OP_READ and resetting ByteBuffer.position().
From: Tom Anderson on 7 Oct 2009 19:40 On Thu, 8 Oct 2009, Gilbert wrote: > Kevin McMurtrie wrote: > >> It doesn't sound like that's going to work reliably. Data existing and >> data flowing aren't the same thing. I think what you need is a message >> dispatcher thread, or demultiplexer if you want to call it that, >> handling the stream. It will route heartbeats off to their handler and >> app data off to another handler. Being that it operates independently >> of app data streams, it will be able to identify exactly the last time >> and type of data that passed through. > > That sounds like it could help with something I'm doing reading messages > from a serial port. There are about 20 message types that require > slightly different handling depending on the message identifier byte. I > don't really want the message dispatcher to have to know about all the > different handlers and the "standard" listener pattern means that all > handlers receive all messages and ignore those that they don't want > which seems wasteful. What I think I'd like to be able to do is to > register a listener for a specific message id. Is there anything > available that I could extend or would I have to roll my own I can't think of anything. But this isn't hard: interface MessageHandler { public void handle(int messageType, InputStream in) throws IOException; } class MessageDispatcher implements Runnable { private final InputStream in; private final Map<Integer, MessageHandler> handlers; public void run() { // you'll need some exception handling here // and some thread control somewhere while (true) { int messageType = in.read(); if (messageType == -1) throw new EOFException(); MessageHandler handler = handlers.get(messageType); if (handler == null) throw new IOException("bad message type: " + messageType); handler.handle(messageType, in); } } } Instead of a map, you could use an array of length 256 (or less), keyed by the byte. Or you could have an enum of message types, turn the message type byte into an enum value, then use an EnumMap. tom -- This is the best kind of weird. It can make a corpse laugh back to death. -- feedmepaper
From: Mark on 8 Oct 2009 06:35
On Wed, 07 Oct 2009 23:27:24 GMT, EJP <esmond.not.pitt(a)not.bigpond.com> wrote: >Mark wrote: >> I am using SocketChannel.read() and SocketChannel.write() >> [non-blocking mode]. > >So therefore the answer to your question is a combination of OP_READ and > resetting ByteBuffer.position(). I don't understand why there is a need to use a ByteBuffer. This method should not be acutally reading any data. -- (\__/) M. (='.'=) Due to the amount of spam posted via googlegroups and (")_(") their inaction to the problem. I am blocking most articles posted from there. If you wish your postings to be seen by everyone you will need use a different method of posting. [Reply-to address valid until it is spammed.] |