Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / November 2005

Tip: Looking for answers? Try searching our database.

Help with NIO

Thread view: 
Xtian.Aguilar.B@gmail.com - 20 Nov 2005 20:19 GMT
I read a lot of NIO concepts in books and internet but I cant find a
good way or explanation of how can I read from Nonbloking I/O.
Some of things that I cant understand:
 1. If I have a buffer of size of 1024, and a client send me a first
message how I know when finish the this first message because maybe
he/she can send more messages. Each time the client send messages, they
migth arrive together?
2. If read about state machines to manage the protocol, but I can find
an example, there is an open source project where using NIO?

Thanks a lot.

PD. sorry my english is not so good.
Gordon Beaton - 21 Nov 2005 07:59 GMT
>   1. If I have a buffer of size of 1024, and a client send me a first
> message how I know when finish the this first message because maybe
> he/she can send more messages. Each time the client send messages, they
> migth arrive together?

This isn't related to NIO or even Java, it's simply the way TCP works.
Your application needs to deal with the possibility that messages may
arrive in pieces or together with neighbouring messages. There are
various ways to do that, some of them are:

- send the length of the message before the message itself
- use a special character or character sequence to terminate each
 message
- send only fixed length messages

/gordon

Signature

[  do not email me copies of your followups  ]
g o r d o n + n e w s @  b a l d e r 1 3 . s e

AWieminer - 21 Nov 2005 09:53 GMT
>>  1. If I have a buffer of size of 1024, and a client send me a first
>>message how I know when finish the this first message because maybe
[quoted text clipped - 10 lines]
>   message
> - send only fixed length messages

I have found it easiest to use a terminator byte (#0 NULL for example)
at the end of message packet. If you send string data NULL should be
fine, but sending a binary files it might not work. Binary file may have
a terminator byte as a data byte. I have done only string-based messages
so it has not been a problem yet.

Basicly what I do is this:
* each connection has a private incomingBuffer ByteArrayOutputStream
* I put all incoming bytes to incomingBuffer
* I analyze buffer data during writing and look for NULL terminator
* if terminator is found I take bytes from startOfBuffer to terminator
byte and create a new message object
* message object is added to FIFO taskhandler queue
* all remaining incomingBuffer bytes stays in a buffer until next
terminator byte is found

To make life easier do not overuse threads. Keep most if not all NIO
handling code in a single thread. This will eliminate many nio bugs for
free. You may use a separate thread for message handler, that removes
messages from synchronized fifo queue.

Handling a response writes is another big task. I keep it in a nio
thread as well. Each connection has a private outgoingMessages list. nio
thread takes pending outgoing messages and writes data to the socket.
Christiansem - 21 Nov 2005 15:16 GMT
thanks folks for your ideas. I'm really glad
I found some code for read from a socketchanel  and I would like what
is your opinion about it.

****************  First one ****************
http://www2.sys-con.com/ITSG/virtualcd/Java/archives/0705/schreiber/index.html

//requestLineBuffer is a ByteBuffer
public void readRequest() throws IOException {
     try {
          if (!requestLineBuffer.hasRemaining()) {
               setError(414, "Request URI too long.");
               prepareForResponse();
              return;
        }
        socketChannel.read(requestLineBuffer);
        if (!isRequestLineRead()) {
            return;
        }
        requestLineBuffer.flip();
        byte[] b = new byte[endOfLineIndex];
        requestLineBuffer.get(b);
        String requestline = new String(b, 0);
        StringTokenizer st
           = new StringTokenizer(requestline, " \r\n");
        String method = st.nextToken();
        uri = st.nextToken();
        File file = new File(uri.substring(1));
        if (st.hasMoreTokens()) {
           protocol = st.nextToken();
        }
        if (!method.equals("GET")) {
           setError(405, "Method " + method
              + " is not supported.");
        } else if (!file.exists() || file.isDirectory()) {
           setError(404, "Resource " + uri
              + " was not found.");
        } else if (!file.canRead()) {
           setError(403, "Forbidden: " + uri);
        } else {
           fileLength = file.length();
           fileChannel
              = new FileInputStream(file).getChannel();
        }
        prepareForResponse();
     } catch (NoSuchElementException nsee) {
        // we didn't read enough tokens
        setError(400, "Bad request.");
     } catch (Exception e) {
        // something else went wrong
        setError(500, "Internal Server Error.");
        prepareForResponse();
        e.printStackTrace();
     }

****************  Second one ****************
http://www.onjava.com/pub/a/onjava/2004/09/01/nio.html?page=3

/**
  * Holds a message that is not fully assembled. This buffer is
fixed-size.
  * If it is exceed, an Exception is raised by the decode() method.
  */
 private byte[] buffer = new byte[BUFFER_SIZE];
 /** Write position on the previous buffer. */
 private int pos = 0;

 public ByteBuffer decode(ByteBuffer socketBuffer) throws IOException
{
   // Reads until the buffer is empty or until a packet
   // is fully reassembled.
   while (socketBuffer.hasRemaining()) {
     // Copies into the temporary buffer
     byte b = socketBuffer.get();
     try {
       buffer[pos] = b;
     } catch (IndexOutOfBoundsException e) {
       // The buffer has a fixed limit. If this limit is reached, them
       // most likely the packet that is being read is corrupt.
       e.printStackTrace();
       throw new IOException(
           "Packet too big. Maximum size allowed: " + BUFFER_SIZE + "
bytes.");
     }
     pos++;

     // Check if it is the final byte of a packet.
     if (b == ETX) {
       // The current packet is fully reassembled. Return it
       byte[] newBuffer = new byte[pos];
       System.arraycopy(buffer, 0, newBuffer, 0, pos);
       ByteBuffer packetBuffer = ByteBuffer.wrap(newBuffer);
       pos = 0;

       return packetBuffer;
     }
   }
   // No packet was reassembled. There is not enough data. Wait
   // for more data to arrive.
   return null;
 }

In which of them I could base my producction application, I mean which
is the better option for  read from a bytebuffer in nonbloking IO for a
producction application.

Thanks a lot for your time

Bye

PD again sorry for my english.
Roedy Green - 21 Nov 2005 09:26 GMT
>  1. If I have a buffer of size of 1024, and a client send me a first
>message how I know when finish the this first message because maybe
>he/she can send more messages. Each time the client send messages, they
>migth arrive together?

A socket is just a stream.  The bytes will appear at the other end in
the same order they were put in.  If your socket stream is composed of
messages you need some way to tell when one message ends and another
begins.

There are four common techniques.

1. fixed length messages, possibly with a type byte on the front of
each message.

2. messages with a length prefix, or embedded lengths for message
add-ons.

3. reserving some character as an inter-message delimiter.

4. using serialised objects. You let java figure it out.

It is not like the old modem days where you have to  resync after a
bout of line noise. You are guaranteed an error free channel.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.