NIO question...

saw this sample code on a webpage...
while (it.hasNext()) {
      SelectionKey sk = (SelectionKey)it.next();
      it.remove();
      int readyOps = sk.readyOps();
      // Disable the interest for the operation
      // that is ready. This prevents the same
      // event from being raised multiple times.
      sk.interestOps(sk.interestOps() & ~readyOps);
...is the setting of interestOps for the selection key necessary? i've not done this in my program and it seems to be working fine.

is the setting of interestOps for the selection key
necessary? i've not done this in my program and it
seems to be working fine.That is something which you should do if e.g the read is handled by another (service) thread. You don't want to get readiness notifications while you are processing.
Kaj

Similar Messages

  • Java NIO question...

    Hey, I've just start reading and programming a client/server using NIO and got to a point where i need to keep a list of connected clients to send them messages as the server processes information it received... How could i handle this selection of clients that i want to send a specific message and how should I store those clients after they connect (I mean, when a client connects, a channel is started, but how can i identify later that a channel is related to THAT client?)
    Thanks in advance
    Message was edited by:
    Lemmerich

    Generally you will associate some kind of client session object with the channel via the attachment. This will also contain the input buffer and whatever you need in your application to identify the client.

  • A NIO question

    I want to use NIO to improve our servlet program,
    but I found that there are only File and socket operation source in the WWW
    I had to use a Channels.newChannel(OutputStream o ) to convert a outputStream to a WritableByteChannel ,
    however this mehtod only redirect the IO operation to stream. It does not improve the performence after I writing the code below:
    // this one use IO method
         public void doGet(HttpServletRequest req, HttpServletResponse res)
         throws ServletException, IOException{
              byte[] bt = new byte[4096*512];
              for(int i = 0; i < 4096*512; i++)
              bt[i] = (byte)i;
              long startTime2 = System.currentTimeMillis();     
              ServletOutputStream sos = res.getOutputStream();
              sos.write(bt);          
              sos.flush();
              sos.close();
              long endTime2 = System.currentTimeMillis();
              System.out.println("IO outPut spend " + (endTime2 - startTime2));     
    // this one use NIO method
         protected void doGet(HttpServletRequest req, HttpServletResponse res)
              throws ServletException, IOException {
    byte[] nb = new byte[4096 * 512];
              for (int i = 0; i < 4096 * 512; i++)
                   nb[i] = (byte) i;
         long startTime2 = System.currentTimeMillis();
              WritableByteChannel wbc = Channels.newChannel(res.getOutputStream());
              wbc.write(ByteBuffer.wrap(nb));
              wbc.close();
              long endTime2 = System.currentTimeMillis();
              System.out.println("NIO outPut use " + (endTime2 - startTime2));
    how could I use NIO to improve the HttpServlet writing speed?
    Thanks u.

    If you have only a single connection, and especially if you have multiple threads, NIO will not help. Its most effective when multiple connections can be processed by a single thread.

  • Two NIO questions

    Hi,
    I'm very intrigued by some of the possible performance enchancements my application can use with NIO. I've got 2 situations that I want to ask the NIO experts about:
    1. In one scenario, I do my own "broadcasts" over TCP (instead of UDP) by populating an OutputStream that is backed by a ByteArrayOutputStream. Then I convert my ByteArrayOutputSTream to a byte[] using toByteArray, and for each one of my OutputStream's I need to broadcast to (these are OutputStreams going thru Sockets), I write the entire byte[] into it. Is there a more efficient way to handle this with NIO? It seems like there is lots of extra bytes being copied in the JVM since the same byte[] is being sent to multiple OutputStreams. Would using a direct ByteBuffer help? Is there a performance penalty for using a ByteBuffer instead of a byte[] if I'm only sending it to one OutputStream?
    2. In another scenario, I'm reading an InputStream. After a certain point of reading the stream, I need to redirect the remaining bytes in the stream to an OutputStream. Currently I'm populating the remaining bytes of the InputStream into a ByteArrayOutputStream, convert it to a byte[] usinng toByteArray(), and then send that out to my designated OutputStream. Once again, it seems like I'm doing unnecessary copying of bytes and the NIO package should have something to directly transfer the bytes from my InputStream to my OutputStream.
    Thank you in advance for any help.
    Mark

    Well here is some pseudo-code for my first scenario.. It's basically restating what I explained earlier but I hope this helps:
    import java.io.*;
    public class Asdf{
    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    public ObjectOutputStream getOutputStream(){
         this.byteArrayOutputStream.reset();
         return new ObjectOutputStream(this.byteArrayOutputStream);
    public void broadcastMessage(ObjectOutputStream oos){
         oos.close();
         Iterator broadcastOutputStreamIter = getBroadcastOutputStreamIter();
         while (broadcastOutputStreamIter.hasNext()){
         ObjectOutputStream curOos = (ObjectOutputStream)broadcastOutputStreamIter.next();
         this.byteArrayOutputStream.writeTo(curOos);
         curOos.flush();
    private Iterator getBroadcastOutputStreamIter(){
         //left out for clarity
    public static void main(String[] args){
         Asdf asdf = new Asdf();
         ObjectOutputStream oos = asdf.getOutputStream();
         oos.writeObject("asdflkj");
         oos.writeBoolean(true);
         broadcastMessage();
    To use NIO, I assume instead of using a ByteArrayOutputStream, I need to use a ByteBuffer, right? How would I tie in my usage of my ObjectOutputStream with the ByteBuffer? Or would I have to just create a new ByteBuffer on my ByteArrayOutputStream within broadcastMessage() and send that out over my Socket's Channel?
    I actually haven't written code for #2 yet b/c I'm trying to figure this out. Basically I want to create an ObjectInputStream from a socket, and after reading an undetermined number of objects from the stream, I want to send the remaining bytes of that stream to another Socket's OutputStream.
    Thanks,
    Mark

  • Nio Question - get() method in ByteBuffer

    I m working on the telnet client program, in the negotiation phase of telnet
    connection, my telnet server returns me FF FB 03 FF FB 01 (WILL SUPPRESS-GO-AHEAD
    WILL ECHO), I read those bytes into a ByteBuffer, and trying to print them out
    to the screen.
    static ByteBuffer bb = ByteBuffer.allocateDirect(1024);
    public static void main(String args[]) throws IOException{
    InetSocketAddress isa = new InetSocketAddress("192.168.1.1", 23);
    SocketChannel sc = null;
    try {
    sc = SocketChannel.open();
    sc.connect(isa);
    bb.clear();
    sc.read(bb);
    bb.flip();
    System.out.println(bb.get());
    For byte FF FB 03 FF FB 01, I got result like -1 -5 3 -1 -5 1
    it seems to me that "print" can't print byte to screen, I therefore tried
    this "new Byte(bb.get()).intValue()", however it gives me the same result
    03 01 are properly displayed, does it mean java interprets 1111 1111 as negative?
    how do I display them as integer value?

    Integer.toHexString(int) will return a string containing the hexadecimal representation of the value of the int.

  • [NIO] custom messages from the netwerk

    Hi you all,
    Yes this is another NIO question :)
    Ok I have the following situation, I've got a NIO server which reads custom messages from the netwerk. These messages consists of an interger and then a variable byte array.
    int -> length of the message
    byte array -> data of message (could be anything)
    On my local network it works fine because I don't have to worry about my read() not reading all the bytes the client send. So I can just use the ByteBuffer.getInt() to read the int and create a buffer for the byte array etc.
    But... on the intenet there is no garentee all the bytes are read. So if only the first 3 bytes of the whole message are in my read buffer and I call the getInt() I'll get an exception.
    How would you fix this? The only garentee is that I will always have 1 byte (except when a connection is closed or other error)
    I could create of small bytebuffer of 4 bytes and wait till it's full and then read the int, but what if I also have a length that can consist out of like 5 or 6 bytes... and I don't know by forehand if it's 4 or 5 or 6... or just 2...
    Any idear would be welcome... or even code if you have the time...
    Grtz
    David

    Use ByteBuffer[] { lengthField, dataField } as a structure for messages. Set the size of the length field statically as part of the protocol. Set dataField's limit to 0. Do readsinto this structure (there is an appropriate read method for an array of ByteBuffers) until there lengthField.remaining() == 0. At this point, read the int/long/whatever from lengthField and set dataField's limit to that. Then do the reads necessary until dataField.remaining() == 0. At this point, you'll have your whole message.
    The reason that I say "do reads" is that on any particular read you may only get one byte's worth of data. Therefore you have to hold this partially completed message in some variable, or as an attachment to the SelectionKey which was selected. As the Channel continually gets selected for OP_READ, you can do the above steps, and if there's not enough left in the channel, you just leave the message partially completed for the next OP_READ. Once it's complete, you do what you need to with it, and replace the attachment or variable with an empty ByteBuffer[] of the above format.
    --Dan                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Online chat, Sept. 19, on NIO APIs

    This is a chat that was originally scheduled for July 16.
    The NIO APIs added to the Java 2 Platform, Standard Edition in Version 1.4 provide new features and improved performance in the areas of buffer management, character-set support, regular-expression matching, file I/O, and scalable network I/O. Learn more about the NIO APIs, and get questions answered in this chat with two key members of the NIO engineering team: Mark Reinhold and Michael McCloskey. They will answer your NIO
    questions on Thursday, September 19 at 11:00 A.M. PDT/6:00 P.M. GMT.
    To join the chat, go to: http://developer.java.sun.com/developer/community/chat/index.html and click on "Join the current session."

    Why not join the chat, andask the guests how the
    Peabody code name came about?Again could this whole thread not have been delivered another way. Surely Sun is able to adverstise or such on their own websites without the need to resort to cross posting across the forums?

  • CharBuffer view on ByteBuffer and No Bytes Written to SocketChannel

    Hi,
    I've actually got two problems that might be connected. I'm new to the java.nio.* package. I wanted to try SocketChannel's to see if I could improve performance.
    If this isn't the appropriate place for java.nio questions, just let me know.
    My first problem is that I create a ByteBuffer by allocating x number of bytes. These bytes are the length of the message I want to send to the server. Then, I attempt to get a CharBuffer view of the ByteBuffer (buffer.asCharBuffer). For some reason, it only returns a CharBuffer with half the capacity of the ByteBuffer. So of course, when I stuff my String into the CharBuffer, it doesn't fit.
    Well, I hack that and make the ByteBuffer twice as big. Which brings me to problem two, my SocketChannel does not write any bytes to the server when told to.
    Here's the code (with hack):
              ByteBuffer buf;
              CharBuffer cbuf;
              SocketChannel sockChan;
              try {
                   int msgLength = message.length();
                   logger.info("Message length=" + msgLength);
                   logger.info("message length in bytes=" + message.getBytes().length);
                   buf = ByteBuffer.allocateDirect(msgLength*2);
                   logger.info("position=" + buf.position());
                   logger.info("capacity=" + buf.capacity());
                   logger.info("limit=" + buf.limit());
                   cbuf = buf.asCharBuffer();
                   logger.info("capacity of cbuf=" + cbuf.capacity());
                   cbuf.put(message);
                   buf.flip();
                   sockChan = SocketChannel.open();
                   sockChan.configureBlocking(true);
                   sockChan.socket().setSoTimeout(TIMEOUT_MS);
                   logger.info("socket configured");
                   sockChan.connect(new InetSocketAddress(ipAddress, portNumber));
                   int numBytesWritten = sockChan.write(buf);
                   logger.info("connected and wrote message. NumBytes writen=" + numBytesWritten);
                   if (numBytesWritten != msgLength) {
                        //throw error
                        logger.error("The number of bytes written do not match the " +
                             "message length (in bytes).");
              } catch (IOException e1) {
                   // TODO Auto-generated catch block
                   e1.printStackTrace();
              }And the console outputs the following:
    [Dec 13, 11:46:17] INFO - Message length=50
    [Dec 13, 11:46:17] INFO - message length in bytes=50
    [Dec 13, 11:46:17] INFO - position=0
    [Dec 13, 11:46:17] INFO - capacity=100
    [Dec 13, 11:46:17] INFO - limit=100
    [Dec 13, 11:46:17] INFO - capacity of cbuf=50
    [Dec 13, 11:46:17] INFO - socket configured
    [Dec 13, 11:46:17] INFO - connected and wrote message. NumBytes writen=0
    [Dec 13, 11:46:17] ERROR - The number of bytes written do not match the message length (in bytes).My batch program freezes at this point. Don't know why it does that either.
    Thanks for any help,
    CowKing

    ByteBuffer (buffer.asCharBuffer). For some reason, it
    only returns a CharBuffer with half the capacity of
    the ByteBuffer.The reason is simply that chars are twice as big as bytes, so you can only get half as many of them into the same space. The capacity of a ByteBuffer is measured in bytes. The capacity of a CharBuffer is measured in chars. The capacity of a DoubleBuffer is measured in doubles.
    Well, I hack that and make the ByteBuffer twice as
    big. Which brings me to problem two, my SocketChannel
    does not write any bytes to the server when told to.As it says in the Javadoc for ByteBuffer, a view buffer has its own position, limit, and mark. When you put data into it the data goes 'through' into the underlying ByteBuffer but the revised position/limit do not. You have to do that yourself manually, remembering to multiply by two as above to account for the difference widths of chars and bytes.

  • Java.nio read/write question

    Hello,
    I just started to learn the java.nio package so I decided to make a simple Echo server. I made a client which reads a line from the keyboard, sends it to the server and the server returns it. It all works except one little detail. Here's little code from the server:
                                 int n = client.read(buffer);
                                 if ( n > 0)
                                     buffer.flip();
                                     client.write(buffer);
                                     Charset charset = Charset.forName("ISO-8859-1");
                                     CharsetDecoder decoder = charset.newDecoder();
                                     charBuffer = decoder.decode(buffer);
                                     System.out.println(charBuffer.toString());
                                     buffer.clear();
                                  }So that works, I send the data and then I receive it back. But only for the client. I also wanted the server to print the line which is the reason for the charset and the decoder. The above code however prints only a blank line. Thus I tried this:
                                 int n = client.read(buffer);
                                 if ( n > 0)
                                     buffer.flip();
                                     Charset charset = Charset.forName("ISO-8859-1");
                                     CharsetDecoder decoder = charset.newDecoder();
                                     charBuffer = decoder.decode(buffer);
                                     System.out.println(charBuffer.toString());
                                     client.write(buffer);
                                     buffer.clear();
                                  }Or in other words I just moved the write() part downwards. So far so good, now the server was actually printing the lines that the client was sending but nothing was sent back to the client.
    The question is how to make both, the send back line and the print line on the server side to work as intended. Also a little explanation why the events described above are happening is going to be more than welcome :)
    Thanks in advance!

    Strike notice
    A number of the regular posters here are striking in protest at the poor
    management of these forums. Although it is our unpaid efforts which make the
    forums function, the Sun employees responsible for them seem to regard us as
    contemptible. We hope that this strike will enable them to see the value
    which we provide to Sun. Apologies to unsuspecting innocents caught up in
    the cross-fire.

  • NIO design question

    Hi,
    I'm looking for advice on how to implement the following architecture in a scalable way. Can NIO be used for this?
    - My application exposes a bunch of servlets. Multiple clients invoke those servlets simultaneously.
    - I want to limit the number of connections across the application (all servlets) and have a separate limit on the number of connections per specific servlet.
    - When a servlet is invoked, I want to push a Callable onto a worker thread (which imposes the above limits) and have the servlet thread recycled back into the web server without closing the underlying connection.
    - The worker thread would eventually service the client, but a single worker thread would service potentially thousands of waiting clients.
    Why do I want to these limits? Because some servlets are very expensive (cpu and memory) and are likely to cause database update collisions.
    The problem is that I don't know how to return from the servlet body without closing the underlying connection. I believe the web container closes it automatically.
    Any ideas?
    Thanks,
    Gili

    Peter__Lawrey wrote:
    cowwoc wrote:
    1) It's container-specific as you mentioned.How many containers are you planning to use?I plan on using Tomcat or GlassFish. I'm not sure which yet.
    2) MaxThreads limits across the entire container instead of on a per-servlet basis.The maximum is per application. You can put each servlet in separate applications (in the same container)
    What is the motivation for having a purely per servlet limit?Some servlets are very computationally expensive and/or are liable to cause frequent database update collisions (using optimistic locking) if I allow too many simultaneous connections.

  • Very simple question on J NIO

    This will be the easiest to answer i guess.
    I have a SocketChannel and i want to read two characters from it and store then in two char variables.
    I dont wanna use the socket().getInputStream().read() function as it is blocking
    and also i want to avail the non-blocking read option using configureBlocking Function.
    thanks for reading the post

    NIO is a lot of work, but there are examples, take a look at Taming the NIO Circus for an example and some pointers about problems.
    The simplest approach is to use threads and streams. It all depends on what your application structure is, whether blocking is a problem. You can also limit the time the read blocks for by using Socket.setSoTimeout.
    You will need to eventually block before you can use the data that you have read. If your application uses Swing, you can use SwingUtilities.invokeLater to post an event to the GUI when the data arrives.

  • Question on use of NIO with je

    I saw the FAQ entry about NIO: http://www.oracle.com/technology/products/berkeley-db/faq/je_faq.html#24
    Could you clarify the problems with NIO and situations it shouldn't be used? Currently we are using it with 3.2 and haven't run into any issues but I don't know if we are just getting lucky.
    -Nick

    What I recall is that the NIO JVM bugs were related to GC. Direct memory is not managed like ordinary heap memory, so a separate (and buggy) mechanism is used in the JVM. The symptoms were very slow GC and OOME. It's possible that Sun has fixed these problems since then, but as Charles said there is no measurable performance benefit for direct memory in JE, so it is no longer used in JE. As Charles says, ByteBuffers are still used, but this is not a use of direct memory.
    --mark                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Java.nio selector non-blocking IO question

    Hi,
    I am designing an interactive server where multiple clients can log on and communicate with the server. I designed a protocol that the client/server use to talk to each other. My server runs a Selector to monitor a ServerSocket, accepting connections and reading continuously from clients.
    Now my question is, since read() on ServerChannel are non-blocking using selector, how can I be sure that my entire protocol message will be read each time selector wakes up? For example, a slow client sends me a 5kb message, in one write() command, can I be sure that I will be able to read the entire message in one non-blocking read() command as well? If not, then the design becomes much more complicated, as I have to pipe each client's input into a handler thread that performs blocking i/o to read a protocol message one at a time. If I do that, then I might as well not use select() at all.
    I did some preliminary tests, and it seems that for my purpose (message of size <= 50kb), a read() command will always be able to read the entire message. But I can't find any documentation on this subject. My guess is that I cannot trust non-blocking I/O as well, which means it does not fit my purpose.
    Any help will be much appreciated.
    Thanks,
    Frank

    You can't be sure a read() will read in all the data from a client in one call.
    For example, say your message from the client to the server is of the following format. <start>message here<end>, where <start> indicates the start of a message and <end> the end of the message. In one read() call you might get "<start>message he". Your server would recognize this is partially correct but it needs the rest of the message. The server would store this and on the second read() you might get "re<end>" for the complete message.
    The purpose of non-blocking I/O is so you don't have to wait around for the second part of the message, you can process other client messages while the first client finishes sending their message. This way other clients aren't waiting around while you(the server) sit and wait for client 1 to finish sending it's data.
    So basically there is no gaurantee you will get a whole message intact. Your protocol will have to deal with partial messages, recognize them, store the partial message in a buffer, and on subsequent reads get the rest of the message.
    Nick

  • Questions about jdk nio charset

    During load test, work threads all wait for reading charset classes from Classloader. Why not keep the stable result in cache? Thanks a lot!
    "ExecuteThread: '25' for queue: 'weblogic.kernel.Default'" daemon prio=1 tid=0x5c941800 nid=0x38ee waiting for monitor entry [5d697000..5d6988c8]
         at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:49)
         - waiting to lock <0x5113ebe0> (a sun.net.www.protocol.jar.JarFileFactory)
         at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:85)
         at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:107)
         at java.net.URL.openStream(URL.java:913)
         at sun.misc.Service.parse(Service.java:203)
         at sun.misc.Service.access$100(Service.java:111)
         at sun.misc.Service$LazyIterator.hasNext(Service.java:257)
         at java.nio.charset.Charset$1.getNext(Charset.java:303)
         at java.nio.charset.Charset$1.hasNext(Charset.java:318)
         at java.nio.charset.Charset$2.run(Charset.java:361)
         at java.security.AccessController.doPrivileged(Native Method)
         at java.nio.charset.Charset.lookupViaProviders(Charset.java:358)
         at java.nio.charset.Charset.lookup(Charset.java:385)
         at java.nio.charset.Charset.isSupported(Charset.java:407)
         at java.lang.StringCoding.lookupCharset(StringCoding.java:82)
         at java.lang.StringCoding.encode(StringCoding.java:363)
         at java.lang.StringCoding.encode(StringCoding.java:380)
         at java.lang.String.getBytes(String.java:590)

    who can tell me how to avoid this? Thanks a lot!

  • Question on NIO

    How Repeater arechitecture in NIO detect a new client has come for the request?

    What's a "repeater architecture" in this context? (ie: what's it got to do with Java networking?)
    Are you looking for information on how to use the NIO API, or are you trying to figure out how the NIO API works?
    This is where I'd start for learning to use the API:
    http://java.sun.com/j2se/1.5.0/docs/guide/nio/
    The examples are of particular interest.

Maybe you are looking for