Non-blocking SSLEngine example

Since the example of using SSLEngine with non-blocking IO that comes with Java is quite limited, I have decided to release my own for anyone who wants to see how I solved the various problems that you must face. The example is designed to be a generic non-blocking server that supports SSL.
This is only meant to be an example, as I wrote this mostly in order to learn how to use the SSLEngine, and therefore has certain limitations, and is not thouroughly tested.
You can download the file at: http://members.aol.com/ben77/nio_server2.tar.gz
Here is also the code for SecureIO, which is roughly analagous to the Java example's ChannelIOSecure:
package nio_server2.internalio;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.concurrent.*;
import javax.net.ssl.*;
import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
* Does IO based on a <code>SocketChannel</code> with all data encrypted using
* SSL.
* @author ben
public class SecureIO extends InsecureIO {
      * SSLTasker is responsible for dealing with all long running tasks required
      * by the SSLEngine
      * @author ben
     private class SSLTasker implements Runnable {
           * @inheritDoc
          public void run() {
               Runnable r;
               while ((r = engine.getDelegatedTask()) != null) {
                    r.run();
               if (inNet.position() > 0) {
                    regnow(); // we may already have read what is needed
               try {
                    System.out.println(":" + engine.getHandshakeStatus());
                    switch (engine.getHandshakeStatus()) {
                         case NOT_HANDSHAKING:
                              break;
                         case FINISHED:
                              System.err.println("Detected FINISHED in tasker");
                              Thread.dumpStack();
                              break;
                         case NEED_TASK:
                              System.err.println("Detected NEED_TASK in tasker");
                              assert false;
                              break;
                         case NEED_WRAP:
                              rereg(SelectionKey.OP_WRITE);
                              break;
                         case NEED_UNWRAP:
                              rereg(SelectionKey.OP_READ);
                              break;
               } catch (IOException e) {
                    e.printStackTrace();
                    try {
                         shutdown();
                    } catch (IOException ex) {
                         ex.printStackTrace();
               hsStatus = engine.getHandshakeStatus();
               isTasking = false;
     private SSLEngine engine;
     private ByteBuffer inNet; // always cleared btwn calls
     private ByteBuffer outNet; // when hasRemaining, has data to write.
     private static final ByteBuffer BLANK = ByteBuffer.allocate(0);
     private boolean initialHandshakeDone = false;
     private volatile boolean isTasking = false;
     private boolean handshaking = true;
     private SSLEngineResult.HandshakeStatus hsStatus = NEED_UNWRAP;
     private boolean shutdownStarted;
     private static Executor executor = getDefaultExecutor();
     private SSLTasker tasker = new SSLTasker();
     private ByteBuffer temp;
      * @return the default <code>Executor</code>
     public static Executor getDefaultExecutor() {
          return new ThreadPoolExecutor(3, Integer.MAX_VALUE, 60L,
                    TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
                    new DaemonThreadFactory());
     private static class DaemonThreadFactory implements ThreadFactory {
          private static ThreadFactory defaultFactory = Executors
                    .defaultThreadFactory();
           * Creates a thread using the default factory, but sets it to be daemon
           * before returning it
           * @param r
           *            the runnable to run
           * @return the new thread
          public Thread newThread(Runnable r) {
               Thread t = defaultFactory.newThread(r);
               t.setDaemon(true);
               return t;
      * @return the executor currently being used for all long-running tasks
     public static Executor getExecutor() {
          return executor;
      * Changes the executor being used for all long-running tasks. Currently
      * running tasks will still use the old executor
      * @param executor
      *            the new Executor to use
     public static void setExecutor(Executor executor) {
          SecureIO.executor = executor;
      * Creates a new <code>SecureIO</code>
      * @param channel
      *            the channel to do IO on.
      * @param sslCtx
      *            the <code>SSLContext</code> to use
     public SecureIO(SocketChannel channel, SSLContext sslCtx) {
          super(channel);
          engine = sslCtx.createSSLEngine();
          engine.setUseClientMode(false);
          int size = engine.getSession().getPacketBufferSize();
          inNet = ByteBuffer.allocate(size);
          outNet = ByteBuffer.allocate(size);
          outNet.limit(0);
          temp = ByteBuffer.allocate(engine.getSession()
                    .getApplicationBufferSize());
     private void doTasks() throws IOException {
          rereg(0); // don't do anything until the task is done.
          isTasking = true;
          SecureIO.executor.execute(tasker);
      * Does all handshaking required by SSL.
      * @param dst
      *            the destination from an application data read
      * @return true if all needed SSL handshaking is currently complete.
      * @throws IOException
      *             if there are errors in handshaking.
     @Override
     public boolean doHandshake(ByteBuffer dst) throws IOException {
          if (!handshaking) {
               return true;
          if (dst.remaining() < minBufferSize()) {
               throw new IllegalArgumentException("Buffer has only "
                         + dst.remaining() + " left + minBufferSize is "
                         + minBufferSize());
          if (outNet.hasRemaining()) {
               if (!flush()) {
                    return false;
               switch (hsStatus) {
                    case FINISHED:
                         handshaking = false;
                         initialHandshakeDone = true;
                         rereg(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                         return true;
                    case NEED_UNWRAP:
                         rereg(SelectionKey.OP_READ);
                         break;
                    case NEED_TASK:
                         doTasks();
                         return false;
                    case NOT_HANDSHAKING:
                         throw new RuntimeException(
                                   "NOT_HANDSHAKING encountered when handshaking");
          SSLEngineResult res;
          System.out.println(hsStatus + "1" + handshaking);
          switch (hsStatus) {
               case NEED_UNWRAP:
                    int i;
                    do {
                         rereg(SelectionKey.OP_READ);
                         i = super.read(inNet);
                         if (i < 0) {
                              engine.closeInbound();
                              handshaking = false;
                              shutdown();
                              return true;
                         if (i == 0 && inNet.position() == 0) {
                              return false;
                         inloop: do {
                              inNet.flip();
                              temp.clear();
                              res = engine.unwrap(inNet, temp);
                              inNet.compact();
                              temp.flip();
                              if (temp.hasRemaining()) {
                                   dst.put(temp);
                              switch (res.getStatus()) {
                                   case OK:
                                        hsStatus = res.getHandshakeStatus();
                                        if (hsStatus == NEED_TASK) {
                                             doTasks();
                                        // if (hsStatus == FINISHED) {
                                        // // if (!initialHandshakeDone) {
                                        // // throw new RuntimeException(hsStatus
                                        // // + " encountered when handshaking");
                                        // initialHandshakeDone = true;
                                        // handshaking=false;
                                        // key.interestOps(SelectionKey.OP_READ
                                        // | SelectionKey.OP_WRITE);
                                        // TODO check others?
                                        break;
                                   case BUFFER_UNDERFLOW:
                                        break inloop;
                                   case BUFFER_OVERFLOW:
                                   case CLOSED:
                                        throw new RuntimeException(res.getStatus()
                                                  + " encountered when handshaking");
                         } while (hsStatus == NEED_UNWRAP
                                   && dst.remaining() >= minBufferSize());
                    } while (hsStatus == NEED_UNWRAP
                              && dst.remaining() >= minBufferSize());
                    if (inNet.position() > 0) {
                         System.err.println(inNet);
                    if (hsStatus != NEED_WRAP) {
                         break;
                    } // else fall through
                    rereg(SelectionKey.OP_WRITE);
               case NEED_WRAP:
                    do {
                         outNet.clear();
                         res = engine.wrap(BLANK, outNet);
                         switch (res.getStatus()) {
                              case OK:
                                   outNet.flip();
                                   hsStatus = res.getHandshakeStatus();
                                   if (hsStatus == NEED_TASK) {
                                        doTasks();
                                        return false;
                                   // TODO check others?
                                   break;
                              case BUFFER_OVERFLOW:
                                   outNet.limit(0);
                                   int size = engine.getSession()
                                             .getPacketBufferSize();
                                   if (outNet.capacity() < size) {
                                        outNet = ByteBuffer.allocate(size);
                                   } else { // shouldn't happen
                                        throw new RuntimeException(res.getStatus()
                                                  + " encountered when handshaking");
                              case BUFFER_UNDERFLOW: // engine shouldn't care
                              case CLOSED:
                                   throw new RuntimeException(res.getStatus()
                                             + " encountered when handshaking");
                    } while (flush() && hsStatus == NEED_WRAP);
                    break;
               case NEED_TASK:
                    doTasks();
                    return false;
               case FINISHED:
                    break; // checked below
               case NOT_HANDSHAKING:
                    System.err.println(hsStatus + " encountered when handshaking");
                    handshaking = false;
                    initialHandshakeDone = true;
                    rereg(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
          if (hsStatus == FINISHED) {
               // if (!initialHandshakeDone) {
               // throw new RuntimeException(hsStatus
               // + " encountered when handshaking");
               initialHandshakeDone = true;
               handshaking = false;
               rereg(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
          System.out.println(hsStatus + "2" + handshaking);
          return !handshaking;
      * Attempts to flush all buffered data to the channel.
      * @return true if all buffered data has been written.
      * @throws IOException
      *             if there are errors writing the data
     @Override
     public boolean flush() throws IOException {
          if (!outNet.hasRemaining()) {
               return true;
          super.write(outNet);
          return !outNet.hasRemaining();
      * @return the largest amount of application data that could be read from
      *         the channel at once.
     @Override
     public int minBufferSize() {
          return engine.getSession().getApplicationBufferSize();
      * Begins or proceeds with sending an SSL shutdown message to the client.
      * @return true if all needed IO is complete
      * @throws IOException
      *             if there are errors sending the message.
     @Override
     public boolean shutdown() throws IOException {
          if (!shutdownStarted) {
               shutdownStarted = true;
               engine.closeOutbound();
          if (outNet.hasRemaining() && !flush()) {
               return false;
          SSLEngineResult result;
          do {
               outNet.clear();
               result = engine.wrap(BLANK, outNet);
               if (result.getStatus() != SSLEngineResult.Status.CLOSED) {
                    throw new IOException("Unexpected result in shutdown:"
                              + result.getStatus());
               outNet.flip();
               if (outNet.hasRemaining() && !flush()) {
                    return false;
          } while (result.getHandshakeStatus() == NEED_WRAP);
          return !outNet.hasRemaining();
      * Reads all possible data into the <code>ByteBuffer</code>.
      * @param dst
      *            the buffer to read into.
      * @return the number of bytes read, or -1 if the channel or
      *         <code>SSLEngine</code> is closed
      * @throws IllegalStateException
      *             if the initial handshake isn't complete *
      * @throws IOException
      *             if there are errors.
      * @throws IllegalStateException
      *             if the initial handshake isn't complete
      * @throws IllegalArgumentException
      *             if the remaining space in dst is less than
      *             {@link SecureIO#minBufferSize()}
     @Override
     public int read(ByteBuffer dst) throws IOException {
          if (!initialHandshakeDone) {
               throw new IllegalStateException("Initial handshake incomplete");
          if (dst.remaining() < minBufferSize()) {
               throw new IllegalArgumentException("Buffer has only "
                         + dst.remaining() + " left + minBufferSize is "
                         + minBufferSize());
          int sPos = dst.position();
          int i;
          while ((i = super.read(inNet)) != 0
                    && dst.remaining() >= minBufferSize()) {
               if (i < 0) {
                    engine.closeInbound();
                    shutdown();
                    return -1;
               do {
                    inNet.flip();
                    temp.clear();
                    SSLEngineResult result = engine.unwrap(inNet, temp);
                    inNet.compact();
                    temp.flip();
                    if (temp.hasRemaining()) {
                         dst.put(temp);
                    switch (result.getStatus()) {
                         case BUFFER_UNDERFLOW:
                              continue;
                         case BUFFER_OVERFLOW:
                              throw new Error();
                         case CLOSED:
                              return -1;
                         // throw new IOException("SSLEngine closed");
                         case OK:
                              checkHandshake();
                              break;
               } while (inNet.position() > 0);
          return dst.position() - sPos;
      * Encrypts data and writes it to the channel.
      * @param src
      *            the data to write
      * @return the number of bytes written
      * @throws IOException
      *             if there are errors.
      * @throws IllegalStateException
      *             if the initial handshake isn't complete
     @Override
     public int write(ByteBuffer src) throws IOException {
          if (!initialHandshakeDone) {
               throw new IllegalStateException("Initial handshake incomplete");
          if (!flush()) {
               return 0;
          int written = 0;
          outer: while (src.hasRemaining()) {
               outNet.clear(); // we flushed it
               SSLEngineResult result = engine.wrap(src, outNet);
               outNet.flip();
               switch (result.getStatus()) {
                    case BUFFER_UNDERFLOW:
                         break outer; // not enough left to send (prob won't
                    // happen - padding)
                    case BUFFER_OVERFLOW:
                         if (!flush()) {
                              break outer; // can't remake while still have
                              // stuff to write
                         int size = engine.getSession().getPacketBufferSize();
                         if (outNet.capacity() < size) {
                              outNet = ByteBuffer.allocate(size);
                         } else { // shouldn't happen
                              throw new RuntimeException(hsStatus
                                        + " encountered when handshaking");
                         continue; // try again
                    case CLOSED:
                         throw new IOException("SSLEngine closed");
                    case OK:
                         checkHandshake();
                         break;
               if (!flush()) {
                    break;
          return written;
     private boolean hasRemaining(ByteBuffer[] src) {
          for (ByteBuffer b : src) {
               if (b.hasRemaining()) {
                    return true;
          return false;
      * Encrypts data and writes it to the channel.
      * @param src
      *            the data to write
      * @return the number of bytes written
      * @throws IOException
      *             if there are errors.
      * @throws IllegalStateException
      *             if the initial handshake isn't complete
     @Override
     public long write(ByteBuffer[] src) throws IOException {
          if (!initialHandshakeDone) {
               throw new IllegalStateException("Initial handshake incomplete");
          if (!flush()) {
               return 0;
          int written = 0;
          outer: while (hasRemaining(src)) {
               outNet.clear(); // we flushed it
               SSLEngineResult result = engine.wrap(src, outNet);
               outNet.flip();
               switch (result.getStatus()) {
                    case BUFFER_UNDERFLOW:
                         break outer; // not enough left to send (prob won't
                    // happen - padding)
                    case BUFFER_OVERFLOW:
                         if (!flush()) {
                              break outer; // can't remake while still have
                              // stuff to write
                         int size = engine.getSession().getPacketBufferSize();
                         if (outNet.capacity() < size) {
                              outNet = ByteBuffer.allocate(size);
                         } else { // shouldn't happen
                              throw new RuntimeException(hsStatus
                                        + " encountered when handshaking");
                         continue; // try again
                    case CLOSED:
                         throw new IOException("SSLEngine closed");
                    case OK:
                         checkHandshake();
                         break;
               if (!flush()) {
                    break;
          return written;
     private void checkHandshake() throws IOException {
          // Thread.dumpStack();
          // System.out.println(engine.getHandshakeStatus());
          outer: while (true) {
               switch (engine.getHandshakeStatus()) {
                    case NOT_HANDSHAKING:
                         initialHandshakeDone = true;
                         handshaking = false;
                         rereg(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                         return;
                    case FINISHED:
                         // this shouldn't happen, I don't think. If it does, say
                         // where.
                         System.err.println("Detected FINISHED in checkHandshake");
                         Thread.dumpStack();
                         break outer;
                    case NEED_TASK:
                         if (isTasking) {
                              while (isTasking) { // TODO: deal with by reg?
                                   Thread.yield();
                                   try {
                                        Thread.sleep(1);
                                   } catch (InterruptedException ex) {
                                        // TODO Auto-generated catch block
                                        ex.printStackTrace();
                              break;
                         doTasks();
                         break;
                    case NEED_WRAP:
                         rereg(SelectionKey.OP_WRITE);
                         break outer;
                    case NEED_UNWRAP:
                         rereg(SelectionKey.OP_READ);
                         break outer;
          handshaking = true;
          hsStatus = engine.getHandshakeStatus();
      * @return true if the channel is open and no shutdown message has been
      *         recieved.
     @Override
     public boolean isOpen() {
          return super.isOpen() && !engine.isInboundDone();
}

That's the reason for checkHandshake(), it is called on every read and write and detects a new handshake and configures the setup properly. As far as the server requesting a new handshake, I did not put that in. It would be simple enough though, you would just need to call SSLEngine.beginHandshake() + then call checkHandshake().
Also, my echo server example had a bug, I forgot to call bu.flip() before queueWrite(), so I fixed that, as well as adding an onConnect method that is called when a connection has been established. The new version should be up at the origional address shortly.

Similar Messages

  • Non-blocking and terminating processes

    Can someone give me an example of using the host.nonblocking to terminate a process or a window that is opened using a webutil_file_Transfer.DB_To_Client when finished using the opened document.
    I am using oracle 10g developer:
    Thanks

    "non-blocking port" and "1:1 oversubscription" are the same.    It's also the same when you are saying "line rate".  

  • Non-blocking Vectored read from SocketChannel fails

    Hi.
    Please look at the code example:
    ByteBuffer tmp1 = ByteBuffer.allocate(500);
    ByteBuffer tmp2 = ByteBuffer.allocate(500);
    ByteBuffer[] tmp = {tmp1, tmp2};
    while ((count = socketChannel.read(tmp)) > 0) {
    + "bytes.");
    When I run this code, (using non-blocking socket channel), the first buffer is read ok, but on the second round of the while loop, I get an IOException, saying: "a non blocking socket operation could not be completed immediately".
    If I put 'tmp1' instead of 'tmp' in the read(), (i.e - use a normal buffer), the read successfully finishes.
    Why?
    I found nothing in the documentation, and in the 'Java NIO' book (Ron Hitchens).
    Help?
    Thanks.

    Please ignore the + "bytes."); inside the while.

  • Persistant non-blocking operation problem

    When using asynchronous database calls with non-blocking methods, I am getting a persistant error on the CreateSQL method call - the error is "OIP-04153: Non-Blocking operation in progress". This is raised even though the database connection has been closed and restarted and no non-blocking operations called. The methods used are similar to the following example code:
    Dim OraDatabase as OraDatabase
    Dim OraStmt as OraSQLStmt
    Dim stat as long
    Dim OraSess as OraSession
    Set OraSess = CreateObject("OracleInProcServer.XOraSession")
    Set OraDatabase =OraSess.OpenDatabase("ExampleDb", "scott/tiger", 0)
    'execute the select statement with NONBLOCKING mode on
    set OraStmt = OraDatabase.CreateSQL ("update emp set sal = sal + 1000", ORASQL_NONBLK)
    'Check if the call has completed
    stat = OraStmt.NonBlockingState
    if stat = ORASQL_STILL_EXECUTING
    MsgBox "Cancelling the asynchronous operation that is underway"
         OraStmt.Cancel
    End if
    I cannot cancel the operation using OraStmt.Cancel because OraStmt Is Nothing!

    Actually, that is not correct. All of the 48 port Gig-E line cards for the 6500 are oversubscribed; it does vary by the degree of oversubscription.
    In a 6506 or a 6509 (with a Sup720) you have (2) 20 Gbps connections (per slot) to the fabric. With a WS-X6748-GE-TX you have a potential for 48 (Full Duplex) Gbps of traffic, but only 2 connections to the fabric. This yields an oversubscription rate of 1.2:1 (or 48:40) assuming a worst case scenario.
    It should be noted that the 24 port 67xx cards are still oversubscribed as well, because they only have one connection to the fabric. There is a potential for 24 Gbps of traffic and only (1) 20 Gbps fabric connection, so it has an identical oversubscription rate.
    By using only 24 of the 48 possible ports, depending on which ones you choose, you should be OK. But I do not know which ports use which fabric connection on the backplane, so I can't assist you in picking them.
    It should be noted that in most environments it is unlikely every port will be a 100% utilized so the risk of dropping packets because of oversubscription is low.

  • Non-Blocking Multicast Sockets in JDK 1.4?

    Hi,
    I've been trying to create non-blocking multicast sockets in JDK1.4, which essentially seems (at this stage) to boil down to the simpler problem of creating a DatagramChannel that uses MulticastSockets, or at least DatagramSockets that can join a Multicast group. Not having found any obvious way to do it, I created this extraordinary hack:
    package java.net; // Wicked, wicked!
    import java.io.*;
    public class MyDatagramSocket {
    public static void join(java.net.DatagramSocket socket, InetAddress addr)
    throws IOExceptio DatagramSocket ds = new DatagramSocket(port);
    ds.setReuseAddress(true);
    MyDatagramSocket.join(ds, InetAddress.getByName("224.0.0.104"));
    DatagramPacket dp = new DatagramPacket(array, 5000);
    ds.receive(dp);          /* READS FINE */
    n
    socket.impl.join(addr); // Uses knowledge of DatagramSocket culled from examining source to access DatagramSocketImpl
    Now I compile this, and drop the class file into my rt.jar files (in the JDK and the JRE), so that I can use MyDatagramSocket.join (DatagramSocket, InetAddress), which looks like it should work from code like this:
    try {
    int port = 58501;
    DatagramChannel dc = DatagramChannel.open();
    dc.socket().setReuseAddress(true);
    dc.socket().bind(new InetSocketAddress(port));
    MyDatagramSocket.join(dc.socket(), InetAddress.getByName("224.0.0.104"));
    byte [] array = new byte[5000];
    ByteBuffer bb = ByteBuffer.wrap(array);
    dc.receive(bb);
    System.out.println("Read from dc");
    } catch (Exception x) {
    x.printStackTrace();
    But it doesn't work - it just doesn't read. A simpler example is this:
    DatagramSocket ds = new DatagramSocket(port);
    ds.setReuseAddress(true);
    MyDatagramSocket.join(ds, InetAddress.getByName("224.0.0.104"));
    DatagramPacket dp = new DatagramPacket(array, 5000);
    ds.receive(dp);          /* READS FINE */
    So I know that my hack is working, but this fails:
    DatagramChannel dc = DatagramChannel.open();
    dc.socket().bind(new InetSocketAddress(port));
    dc.socket().setReuseAddress(true);
    MyDatagramSocket.join(dc.socket(), InetAddress.getByName("224.0.0.104"));
    DatagramPacket dp = new DatagramPacket(array, 5000);
    dc.socket().receive(dp);     /* NEVER READS */
    I've reduced the problem to one of the difference between a java.net.DatagramSocket - the standard DatagramSocket, and a sun.nio.ch.DatagramSocketAdaptor, which is what DatagramChannels seem to use.
    My questions are:
    a) Is there a proper way to do this, without my adding my own classes to java.net?
    b) If NO is the answer to a), any ideas what I'm doing wrong in my code?
    Many thanks for any assistance,
    Craig

    I've encountered the same problem in my code. The datagramChannel never receives incoming data. Doesn't matter the rate at which you send it or anything else. I don't see any way around this problem at the moment. If i find something i'll post it. Interesting enough, my friend who programs with C++ got non-blocking I/O with datagrams to work in windows. So this might just be java.

  • How to handle write errors in non blocking sockets

    Hi,
    I'm using sockets registered with a Selector for read operations. I've seen code examples that put the SocketChannel in non blocking mode before registering it with the selector, and in fact not doing so would cause an IllegalBlockingModeException to be thrown.
    My problem is that I can't handle write errors. The call to write() returns inmediately without throwing any exception. Even worse, when the network timeout expires the selector wakes up and I get an exception on read(). So I can't tell the difference between a real read error and a write error.
    What can I do? Is there a magic method I haven't heard about?
    Thanks

    ejp wrote:
    OK, so what happens is this: you write from your ByteBuffer; if there is room in the socket send buffer, the data is transferred and the transfer count is returned. (If there isn''t, the write returns zero and nothing has happened.) Your application code then continues. Meanwhile TCP is trying to send the data in the send buffer and get an ACK from the peer. If the peer is down as per your test, eventually those write attempts will time out. You will then get a connection reset exception on the next read or write.
    Even worse, when the network timeout expires the selector wakes upCorrect, to tell you there is an error condition pending. This is good, not bad.You're right. This way my program can know that something happened.
    But I still don't understand what the difference between a failed write() and a failed read() is. I mean, the error condition may appear during a send attempt, or it may appear after sending. In both cases I get an error when trying to read. How can my program know if data have been received by the other end?
    Do I have to implement ACK messages in the application level protocol??? It'd be nice if TCP could do this for me...

  • SO timeout relevance in non-blocking NIO ServerSocketChannel

    I converted a threaded blocking server from using the standard blocking IO with a thread for each connection to using non-blocking NIO channels. Works great but I'm trying to understand the SO timeout relevance in the context of non-blocking NIO channels. Is there any relevance and should I set an SO timeout on the ServerSocket associated with a ServerSocketChannel and if so how should I handle it?

    No. Socket timeouts are for blocking mode. If you need timeouts in non-blocking mode you have to do them yourself, taking advantage of the Selector.select(long timeout) method and keeping track of activity times per channel yourself. You should use that select() method anyway, rather than just blocking indefinitely, as it gives you a chance to catch up on housekeeping, dead channels, etc. For example as a very naive approach if nothing happens in say a select timeout of 10 minutes you might want to close all accepted SocketChannels.

  • Serialization + Non-blocking IO + Channels ?

    Hi,
    I use a lot of object serialization. The serialized objects can be big. I would like to transform my server to make it non-blocking so that I don't have to use one thread per connection.
    Do I have to use channels if I want non-blocking IO?
    If yes, how can I achieve object serialization?
    The code below seems to work for small objects, but not for bigger ones (5 Kb, for example). I believe it is due to the fact that the whole object is not read at once by the channel. If so, how can I determine that an object is fully read before desializing it?
    Should I take another appoach?
    Thnaks.
    byte[] byts = new byte[ buffer.remaining() ];
    buffer.get( byts );
    ByteArrayInputStream bais = new ByteArrayInputStream( byts );
    ObjectInputStream ois = new ObjectInputStream( bais );
    Object myObject = ois.readObject();

    Hi,
    It might be a good solution to zip the ObjectStream and the UnZip it when you read from the stream.
    This will decrease the size of the objects alot.
    /Richard

  • Writing Java Non-Blocking Socket Server for  Winsock Client

    Hi.
    Im a newbie to Sockets. I need to write a Non-Blocking Socket server (using java.nio) that accepts connection and reads the data sent by WinSock clients, and write them to another winsock client. Its quite intriguing. How do I do that? Is it possible?
    Thanks in advance
    Arun

    Well, in traditional 4.2 BSD sockets, you'd fill up a set of filedescriptors of connections (an array of bits usually), and push that in the read parameter of a call to 'select'. Select then blocks until at least one of the file descriptors become available for reading, or writing if you also made an fd_set full of file descriptors (but you can usually write freely to a socket, so there is not much use for that). Then you start finding out which of these file descriptors have actually become available for reading, and you pass those to a bunch of worker-threads. The advantage is that your set of worker-threads can be quite small, while your number of connections can still be quite large (unless, of course, everyone of your clients start talking all at once, but that is no different from the one-socket-one-thread-model that java.net.* forces upon you).
    In java, the 'select' call is replaced by a call to java.nio.channels.Selector.select(); and then the fishing out of the selected stuff comes from java.nio.channels.Selector.selectedKeys().
    To add a thingy to a selector, use (for example) java.nio.channel.ServerSocketChannel.register(Selector, ops, att);
    whereby the ops parameter is the kind of action you'd like to select this channel for; SelectionKey.OP_READ etc..
    The workerthread bit is also easy to write, but I leave that to you as an exercise.

  • 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

  • Non-blocking file access?

    1. Did I miss something: is there a way in java 1.5 (or even java 1.6) to read files and query file metadata (size, last modified, that kind of thing) in a non-blocking manner?
    2. Is there a way to figure out where physical harddrive boundaries lie without resorting to tricks like running 'df' and parsing the output, which is rather un-portable? I obviously don't want to create a thread per file read (one aim is that the maximum number of threads is constant - even with a gazillion requests the amount of threads will never exceed a (low) constant.) but just 1 thread to perform all required reads would possibly end up wasting time if there are multiple harddrives and the CPU is idling anyway. I'd guess at this point that 1 thread per physical harddrive handling all file access is the best way to go, but how do I figure out those boundaries?
    3. Is NIO2 (JSR 203) going to add features to work with files in a non-blocking way?
    4. Is there a full-stack (templating, database access, writing web services, serving up the data) web server out there someplace that works entirely on a non-blocking methodology? I don't think so, but I might have missed something. JETTY tries something, but the servlet specs fundamentally do not work with non-blocking I/O, so it doesn't count.
    background:
    I'm writing a non-blocking webserver. KISS is the attitude - so far the basic system and any services (my take on the servlet spec, as the servlet spec doesn't play nice with NIO principles) on it all run inside a single thread, no thread pool.
    So far it all works, and stress testing it with 1000 connections, 200 at the same time shows a process time of about half a millisecond per request, on a simple macbook, which is nice, because that beats apache even at serving up 404s.
    So far I have only written very simple test apps that for example do calculations and the like, nothing that you'd actually do with web apps, like, say, serving (template-powered) data from files on a harddrive.
    Because of the absolute requirement for each service NEVER to block while serving up bytes, manually working with files would be an unbelievable pain on the part of the web service developer. Hence I'm building templating and DB access into the system.
    Unfortunately, I realized, reading NIO specs, that there doesn't seem to be any way to perform file operations in a non-blocking manner (not just reading them, but getting file size and last modified timestamps as well). I'll obviously have to use a lot of caching tactics, but before I can cache, I need to read files somehow.
    The aim of this webserver is basically to survive massive spikes in traffic, be it from digg/slashdot, or from a DDOS attack, as best as possible, and where that isn't possible, to gracefully fall apart. That is, service as many requests as possible at a certain minimum bandwidth per request, prioritizing repeat visitors and site moderators, and deny the rest instantly, instead of just falling apart in shambles as happends in your usual LAMP or servlet design, not serving even 1 request right most of the time.
    Thanks a lot for everyone's time!

    ejp wrote:
    BufferedInputStream will improve the performance by a factor of several thousand because it cuts down on system calls.Well, that might be true if you're reading individual bytes with a call to read(), or making many small read( buffer ) requests. But if you call read( buffer ) with a reasonably sized buffer (BufferedInputStream uses 8192 bytes as a default buffer size), then you're going to get performance equal to or possibly better than a BufferedInputStream.

  • NIO non-blocking i/o- Any advantages for UDP server??

    Hi,
    I am developing a classic UDP-based server which serves hundreds of clients simultaneously. After receiving a simple request from a client, the server replies with a simple response (messages are no larger than 50 bytes).
    What, if any non-blocking-related advantages would there be in using nio? Specifically, if I used select() without turning on non-blocking on the data channel, what do I lose?
    The architecture consists of only one socket for responding to client requests. It uses receive() and send(), not read()/write()/connect().
    Thanks in advance,
    Dan.

    >>
    What, if any non-blocking-related advantageswould
    there be in using nio? Specifically, if I used
    select() without turning on non-blocking on thedata
    channel, what do I lose?You cannot do this. The runtime will throw an
    IllegalBlockingModeException when you tried to
    register it.
    So in order to use select(), your registered channels must
    be in non-blocking mode? Why? That's just the way it is?
    So to conclude, using non-blocking mode provides no real advantage for
    my application. It is only required or else I would not be able to use
    select(), right? If so, what is so good about nio? Can you give an example that is similar to my application which would benefit from the non-blocking characteristic of nio?
    Thanks for your help so far...
    Daniel.
    >>
    The architecture consists of only one socket for
    responding to client requests. It uses receive()and
    send(), not read()/write()/connect().If you are only reading from one socket there are
    theoretical advantages to servicing requests on more
    than one thread, but you would not use non-blocking
    mode to do this.
    However I think some operating systems have
    performance problems when doing this. Look at this
    article under accept serialization:
    http://httpd.apache.org/docs/misc/perf-tuning.html
    The same problems may apply to multi-thread udp socket
    readers.

  • PS does not Provide WSDL for RTNGTYPE Synchronous Non Blocking

    Hi,
    This particular field has 5 Translate values. Of which PS does not provide an example/entry for RTNGTYPE Synchronous Non Blocking Routing in either FSCM or CRM Demo Database.
    Would like to know, if some one has created a Routing Type of Synchronous Non Blocking and implemented that.
    The reason being, that for Service Ops with the RTNGTYPE as Synchronous Non Blocking, PS does not allow us to generate WSDLs...Also, Not sure how to create a Sync Non Blocking Routing for a Sv Op in PS...
    Any help is appreciated...
    Thanks
    Prashant

    Are you sure you have uploaded everything in the gallery folder to the correct location. It can't find the index.html page.

  • SQL Developer blocking vs non-blocking

    Hi,
    Is there a way in SQL Developer 3.0 to have a non-blocking SQL call? In Oracle Forms we can choose between blocking and non-blocking SQL Net connections to the database. Does SQL Developer have the same capability? If so where exactly are those options hidden in the preferences menus?
    Annoyed,
    ScottK
    Edited by: ScottK on Jun 1, 2011 11:20 AM

    Hi ScottK,
    SQLDeveloper locks access to individual connections when they are in use, if you want to simulate
    some aspects of non blocking behaviour you can use other connections.
    The following features might help:
    Use a different connection name back to the same schema in your database - it will be treated as an independent connection and 'blocking' on this connection will not affect your other connections.
    This can be achieved temporarily in the worksheet by:
    ctrl shift n
    which creates a worksheet with new connection independent of your existing worksheet connection
    though connected to the same schema and database.
    -Turloch
    SQLDeveloper team

  • ORA-03118 two-task error while doing a non blocking OCI call

    Hi,
    I have an application that runs on Linux and uses OCI API (version 8.1.6).
    If I do the following in non blocking mode after polling about
    70 times I get the error:
    ORA-03118: two-task coroutine has invalid state
    do {
    call_cnt++;
    rtc = OCIStmtFetch(stmtptr->stmt, oracle_err, 1, OCI_FETCH_NEXT,
    OCI_DEFAULT);
    } while (rtc == OCI_STILL_EXECUTING);
    This doesn't happen all the time but it happens most often on big selects.
    Does anyone have any idea what is happening here?
    I have searched for related information but have come up dry. If anyone
    knows anything or maybe a better place to ask this question please tell me.
    Thanks,
    Barry
    null

    Ask your basis guys to increase the table space...
    check this thread...
    [Error : DBIF_RSQL_SQL_ERROR;
    --- Thanks...

Maybe you are looking for