Why non-blocking write would block usually?

I want to know that why my non-blocking socket's write will consume such a long time. sometimes 400ms worst.
and this is my strace result:
19:17:48.886276 write(1306, "\n\365\31:h#\t\7\237\20\3\21\337\36\276\317\6\3023\6\204\223,-\306\30\322\"\f\1\30\0\n"..., 121) = 121 <0.403088>
It use 0.403088 seconds to finish the write, And I am sure of that the fd 1306 is a non-blocking socket.
Another records shows:
19:15:27.949736 write(995, "\n\365'\236UN\24\10\26Y\16\30\373\26\306\240\36\267z\10\20\342\f\17\301&\253\240\2\325\\\314\354"..., 160) = 160 <0.368412>
19:15:28.410003 write(1466, "\n\365't\360`\20\10\20\342&\253\240\36\267z\10\26Y\26\306\240\16\30\373\2\325\\\f\17\301\314\354"..., 194) = 194 <0.199244>
19:15:28.627854 write(1821, "\n\365'\260*s*\f\17\301\16\30\373\10\26Y\10\20\342\26\306\240\2\325\\&\253\240\36\267z\314\354"..., 160) = 160 <0.397758>
19:15:29.029411 write(755, "\n\365'f\356\1\1&\253\240\36\267z\10\26Y\26\306\240\16\30\373\f\17\301\2\325\\\10\20\342\314\354"..., 160) = 160 <0.399817>
19:15:29.440261 write(614, "\n\365'b\345H\6\36\267z&\253\240\10\26Y\2\325\\\26\306\240\10\20\342\f\17\301\16\30\373\314\354"..., 305) = 305 <0.396985>
19:15:29.846446 write(892, "\n\365'\354\2256t\16\30\373\f\17\301\2\325\\\10\20\342\10\26Y&\253\240\26\306\240\36\267z\314\354"..., 160) = 160 <0.399170>
19:15:30.250257 write(515, "\n\365'\376\343\214i\10\20\342\26\306\240\f\17\301&\253\240\10\26Y\2\325\\\36\267z\16\30\373\314\354"..., 231) = 231 <0.398990>
19:15:30.652666 write(262, "\n\365'\274so\6&\253\240\10\26Y\2\325\\\26\306\240\36\267z\16\30\373\f\17\301\10\20\342\314\354"..., 168) = 168 <0.396569>
19:17:46.885289 write(908, "t\213\16\222\0\0\0\0\240@\33L\0\0\3219\0\0\333J\0\0\2218\0\0\2\0|\203\16\222\0"..., 189) = 189 <0.396330>
19:17:47.351419 write(1529, "\n\365\31\352\2\10\252\36\276\317\30\322\"\6\204\223\6\3023\f\1\30\7\237\20\3\21\337,-\306\0\n"..., 128) = 128 <0.293829>
19:17:47.651080 write(683, "\n\365\31~ZG=\30\322\"\6\204\223\7\237\20\36\276\317\6\3023\3\21\337,-\306\f\1\30\0\n"..., 121) = 121 <0.398178>
19:17:48.062419 write(175, "\n\365\31\224H\260\313\f\1\30\6\3023\3\21\337\36\276\317\6\204\223\7\237\20,-\306\30\322\"\0\n"..., 121) = 121 <0.398811>
19:17:48.467481 write(569, "\n\365\31v5]H\3\21\337\30\322\"\f\1\30\6\3023\6\204\223\7\237\20,-\306\36\276\317\0\n"..., 121) = 121 <0.192335>
19:17:48.663023 write(173, "\n\365\31\376\nJ\0\36\276\317,-\306\7\237\20\30\322\"\3\21\337\6\204\223\6\3023\f\1\30\0\n"..., 121) = 121 <0.206703>
19:17:48.886276 write(1306, "\n\365\31:h#\t\7\237\20\3\21\337\36\276\317\6\3023\6\204\223,-\306\30\322\"\f\1\30\0\n"..., 121) = 121 <0.403088>
BTW, This application is for the service of 3-4K client.
And I do want to ask that:
1.Why non-blocking write will make our process lose the CPU ( I think it is blocked ).
2.What our process waiting for? Why not just return EAGAIN?
3.Can we avoid this problem?
Our server's info:
Linux hz172-96 2.6.32-bpo.5-amd64 #1 SMP Mon May 2 11:40:03 UTC 2011 x86_64 GNU/Linux
Looking forward to your answer, Thank you!

thank you for your answer.
and i have resolve this ploblem in using the linux kernel 2.6.30, using  kernel  2.6.32 before.
but, i don't kown Is there some bug in linux kernel 2.6.32 or for other reason.

Similar Messages

  • 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...

  • About NIO non-blocking socket write method behavior

    Hi all -
    I hope anyone could help in this issue.
    Assume you create a NIO socket and configure its channel in non blocking mode:
    channel.configureBlocking(false);
    then you write a byte buffer into it:
    int sentBytesNum = channel.write(byteBuffer);
    What are the possibilities of sentBytesNum value? I am sure of two possibilities, which are:
    - all data sent so sentBytesNum equals byteBuffer data size (limit minus position before sending) (after sending the limit and position of byteBuffer are the same)
    - no data is sent so sentBytesNum is zero and byteBuffer limit and postion did not change, so we shall use a write selector to test when the channel will be ready for write to write the data.
    What I am not sure about and need someone to confirm is the third possibility:
    - only a part of data is sent (according to the available free space of socket output buffer) so sentBytesNum is more than zero but less than data size and byteBuffer position is advanced by the value of sentBytesNum, might this possibility happen??
    If yes, so we should manage to hold the non sent part of byteBuffer till the channel becomes ready for write (we can know that using write selector) so we can write it to channel???
    Thanks for help,
    Rocka

    Yes, case three can occur. The usual NIO write loop looks like this:
    int count = 0;
    while (buf.position() > 0)
      buf.flip();
      count = ch.write(buf);
      buf.compact();
      if (count == 0)
        break;
    }This will run until buf.position() == 0 or count == 0. If the partial write case happens it will loop one more time and probably get a 0 count.
    At the end of the loop, if buf.position() > 0 there is still unwritten data and at this point you should register for OP_WRITE and return to the selector. Otherwise if there is no data unwritten you should deregister OP_WRITE as you have nothing to write and aren't interested in the event any longer.
    If you are reading something and writing at the same time the logic goes like this:
    while (inch.read(buf) >= 0 || buf.position() > 0)
      // etc
    }This will read until EOF occurs and either buf.position() is zero or a zero length write occurred.

  • NIO Non-Blocking Server not Reading from Key

    I have created a NIO non blocking server (below) and it will not pick up any input from the client.... My log doesnt even show that it enters the readKey() method, so it must be something before. Any help would be appreciated.
    Scott
    package jamb.server;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.channels.ClosedChannelException;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.channels.spi.SelectorProvider;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.logging.Logger;
    import java.util.prefs.Preferences;
    import jamb.server.client.Client;
    public class Server {
            private Selector selector;
            private ServerSocketChannel serverChannel;
            private static Logger logger = Logger.getLogger("jamb.server");
            private static Preferences prefs =  Preferences.systemRoot().node("/jamb/server");
            public void init() {
                    logger.entering("jamb.server.Server", "init");
                    //Get a selector...
                    try {
                            selector = SelectorProvider.provider().openSelector();
                            //Open the SocketChannel and make it non-blocking...
                            serverChannel = ServerSocketChannel.open();
                         serverChannel.configureBlocking(false);
                            //Bind the server to the port....
                            int port = prefs.getInt("Port", 4000);
                            logger.config("Server configured on port " + port + " (default: 4000)");
                         InetSocketAddress isa = new InetSocketAddress(
                                    InetAddress.getLocalHost(), port);       
                         serverChannel.socket().bind(isa);
                    } catch (IOException ioe) {
                            logger.severe ("IOException during server initialization!");
                    logger.exiting("jamb.server.Server", "init");
            public void run() {
                    logger.entering("jamb.server.Server", "run");
                    int bufferSize = prefs.getInt("BufferSize", 8);
                    logger.config("Buffer size set to " + bufferSize + " (default: 8)");
                    SelectionKey acceptKey = null;
                    try {
                            acceptKey = serverChannel.register(
                                    selector, SelectionKey.OP_ACCEPT);
                    } catch (ClosedChannelException cce) {
                    try {
                            while (acceptKey.selector().select() > 0) {
                                    Set readyKeys = selector.selectedKeys();
                                    Iterator i = readyKeys.iterator();
                                    while (i.hasNext()) {
                                            //logger.finest("Processing keys...");
                                            //Get the key from the set and remove it
                                            SelectionKey currentKey = (SelectionKey) i.next();
                                            i.remove();
                                            if (currentKey.isAcceptable()) {
                                                    logger.finest("Accepting key...");
                                                    acceptKey(currentKey);
                                            } else if (currentKey.isReadable()) {
                                                    logger.finest("Reading key...");
                                                    readKey(currentKey, bufferSize);
                                            } else if (currentKey.isWritable()) {
                                                    //logger.finest("Writing key...");
                                                    writeKey(currentKey);
                    } catch (IOException ioe) {
                            logger.warning("IOException during key handling!");
                    logger.exiting("jamb.server.Server", "run");
            public void flushClient (Client client) {
                    try {
                            ByteBuffer buf = ByteBuffer.wrap( client.getOutputBuffer().toString().getBytes());
                            client.getChannel().write(buf);
                    } catch (IOException ioe) {
                            System.out.println ("Error writing to player");
                    client.setOutputBuffer(new StringBuffer());
            private void acceptKey (SelectionKey acceptKey) {
                    logger.entering("jamb.server.Server", "acceptKey");
                    //Retrieve a SocketChannel for the new client, and register a new selector with
                    //read/write interests, and then register
                    try {
                            SocketChannel channel =  ((ServerSocketChannel) acceptKey.channel()).accept();
                            channel.configureBlocking(false);
                            SelectionKey readKey = channel.register(
                                    selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE  );
                            readKey.attach(new Client(this, channel));
                    } catch (IOException ioe) {
                            System.out.println ("Error accepting key");
                    logger.exiting("jamb.server.Server", "acceptKey");
            private void readKey (SelectionKey readKey, int bufSize) {
                    logger.entering("jamb.server.Server", "readKey");
                    Client client = (Client) readKey.attachment();
                    try {
                            ByteBuffer byteBuffer = ByteBuffer.allocate(bufSize);
                            int nbytes = client.getChannel().read( byteBuffer );
                            byteBuffer.flip();
                            Charset charset = Charset.forName( "us-ascii" );
                            CharsetDecoder decoder = charset.newDecoder();
                            CharBuffer charBuffer = decoder.decode(byteBuffer);
                            String text = charBuffer.toString();
                            client.getInputBuffer().append(text);
                            if ( text.indexOf( "\n" ) >= 0 )
                                    client.input();
                    } catch (IOException ioe) {
                            logger.warning("Unexpected quit...");
                            client.disconnect();
                    logger.exiting("jamb.server.Server", "readKey");
            private void writeKey (SelectionKey writeKey) {
                    //logger.entering("jamb.server.Server", "writeKey");
                    Client client = (Client) writeKey.attachment();
                    if (!client.isConnected()) {
                            client.connect();
                    //logger.exiting("jamb.server.Server", "writeKey");

    From my own expierence with the NIO (Under Windows XP/ jdk1.4.1_01); you can't seem to set READ and WRITE at the same time.
    The program flow I usually end up with for a echo server is:
    When the selector.isAcceptable(): accept a connection; register for READs
    In the read event; write the incoming characters to a buffer; register for a WRITE and add the buffer as an attachment.
    In the write event; write the data to the socket If all the data was written; register for a READ; otherwise register for another WRITE so that you can write the rest.
    Not sure if that the "proper" way; but it works well for me.
    - Chris

  • What is non blocking IO?

    I have heard that 1.4 supports non blocking IO, and that this is greath for servers. What is it, how does it work and why is it so good?

    I could be wrong - but if they have not yet done so
    a good optimization would be to rearrange the
    select list - such that the sockets that have
    an event appears at the top of the list.
    This way - when the select completes - it tells
    you that there are - say 2 - active events - you
    would then just read the first two channels on
    the select list.From the API javadoc:
    The selected-key set is the set of keys such that each key's channel was detected to be ready for at least one of the operations identified in the key's interest set during a prior selection operation. This set is returned by the selectedKeys method. The selected-key set is always a subset of the key set.
    ie- select and iterate. No polling involved.
    They just completed the java EventListener model
    for the GUI. It would have been simple and clean
    to implement a similar model for io. You have
    the io channel - you would just attach an event
    listener to it much like you would do for a control.
    When an io finishes on a channel, you would be
    told immediately the channel that the io completed
    and what event occured - read, write etc.
    Now you could have a million sockets
    ( if ever unix could support that many file
    discriptors )
    and you when an io completes no need to poll
    a bunch of idle sockets.Question: What thread would this run in?
    * Does it run in the network layer? How many concurrent event notifications can the network layer at any one time? Is it likely it would be an EventQueue-esque single thread?
    * Does it spawn a new thread for each event? This would certainly yield worse results than spawning a new thread for each socket, since each socket would generate a vast number of events.
    * Does it have a thread pool to deal with the events? Then you would be using exactly the same model as java.nio's Selector.
    FYI: The windows NT asynchronous IO model uses
    an event model - IO completion ports. It is far more
    modern, advanced and efficient that the select / poll
    model used in unix.Do you have any links for more information?
    Sun could have incorporated the most modern / best
    features into java and make it competitive. Instead
    they went for least common denominator.Sun's nio package was (somewhat) based on a community project, and was integrated into Java on JSR-051
    http://www.cs.berkeley.edu/~mdw/proj/java-nbio/
    If there were such an initiative for NT-style asynchronous IO, and this was proven to be more efficient, then I imagine it will be much more likely to be integrated with the language.
    If it isn't, you could still use the community-based implementation, as you could with the nbio package before 1.4 was released.
    Just because Sun doesn't do something, doesn't mean you can't!

  • 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.

  • FileChannel.transferTo() using non-blocking SocketChannel

    I'm looking to use FileChannel.transfer(From/To) for performing file transfers over a network. On the uploading side I find that even though I set the SocketChannel to non-blocking mode, the loop manages to send files as large as 30MB in only a single transferTo() invocation. What I'm hoping for is to have a series of partial writes so that I might generate progress notifications, which does occur on the downloading side with transferFrom(). I don't think a file that large should be transferred in one pass so I'm thinking that this is caused by either some internal buffer allocation issue or a goof-up on my part.
    Thanks in advance for any input and here's the uploading code:
    public void upload( String fileName ) {
    FileInputStream fileStrm = null;
    FileChannel fileChan = null;
    FileLock fileLock = null;
    SocketChannel sockChan = null;
    Selector selector = null;
    try {
    // Lock the source file.
    file = new File( fileName );
    fileStrm = new FileInputStream( file );
    fileChan = fileStrm.getChannel();
    fileLock = fileChan.lock( 0L, Long.MAX_VALUE, true );
    // Open a server socket bound to an arbitrary port.
    servChan = ServerSocketChannel.open();
    servChan.socket().bind( new InetSocketAddress( 0 ) );
    // Wait for a single connection and close the server socket.
    sockChan = servChan.accept();
    servChan.close();
    sockChan.configureBlocking( false );
    selector = Selector.open();
    SelectionKey selectorKey = sockChan.register( selector, SelectionKey.OP_WRITE );
    // Loop until transfer has completed.
    int fileSize = ( int ) file.length();
    int sizeLeft = fileSize;
    while ( sizeLeft > 0 ) {
    // Wait for data to read, then transfer it.
    if ( selector.select() == 1 && selectorKey.isWritable() ) {
    sizeLeft -= ( int ) fileChan.transferTo( fileSize - sizeLeft, sizeLeft, sockChan );
    // Generate a progress notification here such as:
    // monitor.bytesTransferred( fileSize - sizeLeft );
    catch ( IOException ex ) {
    ex.printStackTrace();
    finally {
    try {
    // Cleanup.
    if ( selector != null )
    selector.close();
    if ( sockChan != null )
    sockChan.close();
    if ( fileLock != null )
    fileLock.release();
    if ( fileChan != null )
    fileChan.close();
    if ( fileStrm != null )
    fileStrm.close();
    catch ( IOException ex ) {
    ex.printStackTrace();
    -Edwin

    Actually, the sending process appears way ahead of the receiving one, where the send seems to finish in a blink while the receive takes several seconds to complete. In other words, the transferTo() completes in one loop, while the transferFrom() performs many with delays in between. I'd guess all that data is sitting in some large outbound buffer at the sender, which would explain why it seems to finish too quickly. If I split the send into smaller chunks, the two sides run quite nearly at the same pace as expected.
    The receiver already sleeps by way of a select() against a non-blocking SocketChannel, so I'll try reducing the buffer sizes as you suggest.

  • Broken Pipe with Non-blocking Socket

    Hello,
    I write a Unix Agent who connect on a Windows Server with socket...
    Working well on Linux but on Solaris my problem is:
    -When my agent is running before server at connection all seems OK: Connect, Select and Getsockopt but when I try to send data I have always EPIPE Signal but I can receive datas from server !
    - When my agent is strarting after the server all it's Ok
    I don't unserstand this appears on Solaris SPARC 8 and Solaris 9 Intel ...
    Please Help is there something special with non-blocking sockets on Solaris ?
    Thanks

    Can't help you much but what I would recommend is that you
    insure that your pipes are opened for both read/write, even
    though you are only going to read or write from it. This insures
    that the pipe does not close down when you hit EOF.

  • Non-Blocking Writing and Strings

    Hello.
    My question is simple, is it possible to write strings using a non-blocking method?
    I was praying that there was a method in the NIO API that allowed me to, yet i can't find one.
    If the answer is blatantly obvious please forgive me, i'm tired and hungry :)
    Thank you for looking at this topic

    Strings are written to files or sockets using a certain encoding. I usually use UTF-8, but your application might be different.
    1. Get the SocketChannel from your non-blocking socket.
    SocketChannel ch = mySocket.getChannel(); // mySocket is java.net.Socket2. Make a CharBuffer out of the String you want to send.
    CharBuffer chars = CharBuffer.wrap(myString); // myString is your data3. Encode it so it becomes a ByteBuffer. I'll use the [UTF-8|http://www.joelonsoftware.com/articles/Unicode.html] Charset here.
    ByteBuffer bytes = Charset.forName("UTF-8").encode(chars);4. Use the write(ByteBuffer) method in the SocketChannel from 1.
    ch.write(bytes);Import declarations:
    import java.nio.channels.SocketChannel;
    import java.nio.CharBuffer;
    import java.nio.ByteBuffer;
    import java.nio.charset.Charset;s

  • Non-Blocking call to read the Keyboard

    does anyone know how to make a JAVA program make a non-blocking call to read the keyboard? eg. write a program which generates prime number until a keyboard key is pressed.

    if you use a gui you can use keyListener
    Would work only if your gui elements have focus right now.

  • Non-Blocking I/O Implementation Issue

    Hi All,
    I am trying out the latest JDK 1.4 java.nio.* package. I modified the NBTimeServer and wrote a client which connects to the NBTimeServer and tries to pass messages to and fro. I always succeed to pass on roundtrip of msgs and then Server blocks my client forever. I have modified NBTimeServer to accomodate one client only. Any help or comments on this would be really appreciated. Code is below. Feel free to try it out if want to see what I am trying to convey in this message.
    /*******Server Code*******/
    Modified this code to test mulitple to and fro msgs between client and server.
    Only one client will ever be able to connect to this server during life of a server.
    My point here is to demonstrate the to and fro comm between one client and one server
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.net.*;
    import java.util.*;
    import java.nio.charset.*;
    import java.util.regex.*;
    // Listen on a port for connections and write back the current time.
    public class NBTimeServer {
    private static final int DEFAULT_TIME_PORT = 8900;
    // Constructor with no arguments creates a time server on default port.
    public NBTimeServer() throws Exception {
         acceptConnections(this.DEFAULT_TIME_PORT);
    // Constructor with port argument creates a time server on specified port.
    public NBTimeServer(int port) throws Exception {
         acceptConnections(port);
    // Accept connections for current time. Lazy Exception thrown.
    private static void acceptConnections(int port) throws Exception {
         // Selector for incoming time requests
         Selector acceptSelector = SelectorProvider.provider().openSelector();
         Selector rwSelector = SelectorProvider.provider().openSelector();
         // Create a new server socket and set to non blocking mode
         ServerSocketChannel ssc = ServerSocketChannel.open();
         ssc.configureBlocking(false);
         // Bind the server socket to the local host and port
         InetAddress lh = InetAddress.getLocalHost();
         InetSocketAddress isa = new InetSocketAddress(lh, port);
         ssc.socket().bind(isa);
         // Register accepts on the server socket with the selector. This
         // step tells the selector that the socket wants to be put on the
         // ready list when accept operations occur, so allowing multiplexed
         // non-blocking I/O to take place.
         SelectionKey acceptKey = ssc.register(acceptSelector,
                             SelectionKey.OP_ACCEPT);
         int keysAdded = 0;
         // Here's where everything happens. The select method will
         // return when any operations registered above have occurred, the
         // thread has been interrupted, etc.
         while ((keysAdded = acceptSelector.select()) > 0) {
         // Someone is ready for I/O, get the ready keys
         Set readyKeys = acceptSelector.selectedKeys();
         Iterator i = readyKeys.iterator();
         // Walk through the ready keys collection and process date requests.
         while (i.hasNext()) {
              SelectionKey sk = (SelectionKey)i.next();
              i.remove();
              // The key indexes into the selector so you
              // can retrieve the socket that's ready for I/O
              ServerSocketChannel nextReady =
              (ServerSocketChannel)sk.channel();
              // Accept the date request and send back the date string
              Socket s = nextReady.accept();
                        SocketChannel sc = s.getChannel();
    System.out.println("Got client channel..");
              sc.configureBlocking(false);
              SelectionKey readKey = sc.register(rwSelector,
                             SelectionKey.OP_READ|SelectionKey.OP_WRITE);                     
              int count = 0;
    while(true) {
    if((count = rwSelector.select(1000L)) > 0) {
    Set readKeys = rwSelector.selectedKeys();
    Iterator i1 = readKeys.iterator();
    while(i1.hasNext()) {
    System.out.println("Loop in Iterator");
    SelectionKey sk1 = (SelectionKey)i1.next();
    i1.remove();
    if(sk1.isReadable()) {
    DataInputStream sin = new DataInputStream(new BufferedInputStream(s.getInputStream(), 4096));
    System.out.println(sin.readInt());
    if(sk1.isWritable()) {
    DataOutputStream sout = new DataOutputStream(new BufferedOutputStream(s.getOutputStream(), 4096));
    PrintWriter out = new PrintWriter(sout, true);
              Date now = new Date();
              out.println(now);
    // Entry point.
    public static void main(String[] args) {
         // Parse command line arguments and
         // create a new time server (no arguments yet)
         try {
              NBTimeServer nbt = new NBTimeServer();
         } catch(Exception e) {
              e.printStackTrace();          
    /******End Server Code********/
    /*****Begin Client Code********/
    import java.io.*;
    import java.net.*;
    import java.util.*;
    // Listen on a port for connections and write back the current time.
    public class NBTimeClient {
    private static final int DEFAULT_TIME_PORT = 8900;
    public static void main(String args[]) throws Exception {
    InetAddress lh = InetAddress.getLocalHost();
    Socket s = new Socket(lh, DEFAULT_TIME_PORT);
    DataInputStream din = new DataInputStream(new BufferedInputStream(s.getInputStream(), 4096));
    DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(s.getOutputStream(), 4096));
    //Read the time
    System.out.println(din.readLine());
    //send some junk which is read by server
    dout.writeInt(1299);
    dout.flush();
    //read time again -- I never get anything here and I am blocked here...
    System.out.println(din.readLine());
    //send some junk back to the server
    dout.writeInt(1299);
    dout.flush();
    s.close();
    /*******End Client Code**********/
    thanks,
    Xtrimity

    The reason it blocks forever is that you need to keep reusing your main select. That is where the non-blocking event will come from. Here is a bit of code that doesn't block forever.
    Tim
    http://tim.owlmountain.com
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.net.*;
    import java.util.*;
    import org.apache.log4j.*;
    public class NBServer3 {
    int _port = 4000;
    Selector _selector = null;
    ServerSocketChannel _selectableChannel = null;
    int _keysAdded = 0;
    static Category log =
    Category.getInstance(NBServer3.class.getName());
    static String QUIT_SERVER = "quit";
    public NBServer3() {
    public NBServer3( int port ) {
    this._port = port;
    public void initialize()
    throws IOException {
    this._selector = SelectorProvider.provider().openSelector();
    this._selectableChannel = ServerSocketChannel.open();
         this._selectableChannel.configureBlocking(false);
         InetAddress lh = InetAddress.getLocalHost();
         InetSocketAddress isa = new InetSocketAddress(lh, this._port );
         this._selectableChannel.socket().bind(isa);
    public void finalize()
    throws IOException {
    this._selectableChannel.close();
    this._selector.close();
    public void acceptConnections()
    throws IOException {
    Selects a set of keys whose corresponding channels are ready for I/O
    operations. This method performs a non-blocking selection operation.
    If no channels have become selectable since the previous selection
    operation then this method immediately returns zero.
    Returns:
    The number of keys, possibly zero, whose ready-operation sets
    were updated by the selection operation
    do {
    SelectionKey acceptKey =
    this._selectableChannel.register( this._selector,
    SelectionKey.OP_ACCEPT );
    log.debug( "Acceptor loop..." );
    while (( this._keysAdded = acceptKey.selector().select()) > 0 ) {
    log.debug( "Selector returned "
    + this._keysAdded + " ready for IO operations" );
    Set readyKeys = this._selector.selectedKeys();
    Iterator i = readyKeys.iterator();
    while (i.hasNext()) {
    SelectionKey key = (SelectionKey)i.next();
    i.remove();
    if ( key.isAcceptable() ) {
    ServerSocketChannel nextReady =
    (ServerSocketChannel)key.channel();
    log.debug( "Processing selection key read="
    + key.isReadable() + " write=" + key.isWritable() +
    " accept=" + key.isAcceptable() );
    Socket s = nextReady.accept();
    s.getChannel().configureBlocking( false );
    SelectionKey readKey =
    s.getChannel().register( this._selector,
    SelectionKey.OP_READ );
    readKey.attach( s );
    else if ( key.isReadable() ) {
    SelectableChannel nextReady =
    (SelectableChannel) key.channel();
    log.debug( "Processing selection key read="
    + key.isReadable() + " write=" + key.isWritable() +
    " accept=" + key.isAcceptable() );
    Socket socket = (Socket) key.attachment();
    BufferedReader in = new BufferedReader(
    new InputStreamReader( socket.getInputStream() ));
    String line = null;
    if ( (line = in.readLine() ) != null )
    log.debug( line );
    log.debug( "End acceptor loop..." );
    } while ( false ); //FIXIT tim this should be false. justa test
    public static void main( String[] args ) {
    BasicConfigurator.configure();
    NBServer3 nbServer = new NBServer3();
    try {
    nbServer.initialize();
    } catch ( IOException e ) {
    e.printStackTrace();
    System.exit( -1 );
    try {
    nbServer.acceptConnections();
    catch ( IOException e ) {
    e.printStackTrace();
    log.error( e );

  • Non-blocking SocketChannel and close - huh?

    It looks like closing a socketchannel that is in non-blocking mode can result in a dead drop of the connection, with some bytes that have already been sent and accepted (as in, 'consumed' from the buffer) being completely dropped.
    In fact, I'm generally confused: Actual C non-blocking code has a similar setup for 'close' as you can see in SocketChannel's OP_CONNECT behaviour - just because you want to connect the socket doesn't mean it magically happends without blocking. Wait for a ready flag, then try again.
    It should work the same way with close (you try to close, but it may not be possible without blocking).
    Is this a huge gaping bug that no one quite figured out just yet, or did I miss something? I loathe to turn on linger, as that's just a crapshoot (you never know if it actually gets through. You could run into funny surprises once the server gets a bit busy. I'd rather not) and tends to cause massive leaks on linux, at least according to some google searches.
    There seems to be slightly better performance (in that I have always received all data sofar) if I close the socket instead of the channel (socketChannel.socket().close() instead of socketChannel.close()) - but this has been a random attempt at 'making it work', and I can't find any documentation that backs up that this will DEFINITELY not lose any information without letting me know somehow. That still sounds impossible with this approach.

    Actual C non-blocking code has a similar setup for
    'close' as you can see in SocketChannel's
    OP_CONNECT behaviour ...No it doesn't. I don't know what you mean by this.
    Closing a socket is asynchronous, but it shouldn't lose any data - if the data can be delivered it will be, followed by the FIN. You don't know when it is delivered, and you don't get to hear about any errors such as an RST coming from the other end, say if it decided to close before reading all the data, or if some intermediate router hung you up.
    I'm wondering if you are really dealing with all the short write and zero length write possibilities, i.e. whether the data isn't really still in your output buffer. Don't wish to teach you to suck eggs but there are some subtleties here.
    Setting a positive linger timeout doesn't really help because Java doesn't tell you if the timeout expired. (I only asked for this about four years ago). You get to wait while any pending data is delivered, but you still have to guess about whether it all went or the timeout expired, and the behaviour after the timeout expires is platform-dependent: some (Windows) issue an RST, others (Unix) keep trying.
    Blocking or non-blocking mode shouldn't make any difference to this (except that Linux will block on a positive linger timeout even in non-blocking mode, which is wrong), and whether you close the channel or the socket is immaterial as one calls the other anyway.
    The reason why OP_CONNECT is different in blocking/non-blocking modes is that in blocking mode it won't return until the SYN-ACK is received, while in non-blocking mode it just sends the SYN and relies on you calling connect() again (at the C level) to collect the SYN-ACK, or not - this is what finishConnect() tells you.
    tends to cause massive leaks on linux, at least
    according to some google searchesIt can't, unless you are referring to the Helix client thing, which appears to be just a badly designed C++ class library with, for some reason, its own linger implementation outside the kernel.

  • HTTP Web Proxy using Non Blocking IO

    Resolved Thanks................

    client.register(selector, SelectionKey.OP_READ
    | SelectionKey.OP_WRITE);OP_READ only at this stage. OP_WRITE is always 'ready' unless the socket send buffer is full, so your selector will just spin. Don't register OP_WRITE until you have something to write.
    ByteBuffer bferClient = ByteBuffer.allocate(4096);You're doing this every time around the loop, and you don't even know whether the key is readable yet. Do it when you accept a connection, and save it as the key attachment for that channel.
    client.configureBlocking(false);It's already in non-blocking mode. Why are you doing this again?
    try {
    if ((bytesRead = client.read(bferClient)) != -1) {
    bferClient.flip();
    String msgFromClient = new String(bferClient.array());new String(bferClient.array(), 0, bferClient.limit()-1), but you're assuming you got a complete command here. You may not have. That's another reason why you need a ByteBuffer per channel.
    channel.connect(socketAddress);You should do that in non-blocking mode, register the channel for OP_CONNECT, and let the select loop take care of finishing the connection.
    channel.write(bferClient);The incoming command was CONNECT. You don't write that upstream.
    if (!"".equals(msgFromClient.trim())) {
    int bytesReadServer;
    byte[] reply = new byte[4096];
    try {
    ByteBuffer bufferNIO = ByteBuffer.allocateDirect(1024);
    while ((channel.read(bufferNIO)) != -1) {
    bufferNIO.flip();
    client.write(bufferNIO);
    bufferNIO.clear();
    }And you don't do any of this here. You register the new channel for OP_CONNECT, then when you get that do finishConnect() and then register it for OP_READ, and proceed around your select loop. You also need to associate this channel with the channel you read the CONNECT from. So you really need a key attachment object for the original channel that contains its byte buffer and the upstream channel; similarly the upstream channel needs a key attachment that contains its buffer and its downstream channel. The effect of doing all this stuff here instead of around the select loop is that you are never getting back to the select loop: you are handling this one client here, in blocking mode, until the connection is dropped. Completely wrong.
    } catch (IOException e) {Hang on. If bytesRead was -1 you must close the channel.
    e.printStackTrace();And if you get any IOException here you must also close the channel.
    if (channel != null) {
    try {
    channel.close();This is a really strange place to close this channel.
    When you get all that fixed up, post your code and I'll tell you how to handle OP_WRITE.

  • Both blocking and non-blocking io

    I'm wondering if this scenario is possible with the new nio classes:
    I have a caching server. Clients connect to the server and occasionally send requests for objects. I'd like to use the nio non-blocking APIs to detect that there is a read pending on a socket. However, once I detect this, I'd like to go into a blocking loop to process the request. After this done, I'd like to go back into non-blocking mode and wait for another request.
    It seems like this should be possible but the (woefully lacking) documentation isn't clear. Neither is the source code, apparently.
    I've got a test case working but I was hoping someone could validate for me that this is support behavior. It's done by waiting for the isReadable() key then calling socket.keyFor(selector).cancel(); and then socket.configureBlocking(true); The reads are then done in blocking mode until the request is done and then the socket is registered with the selector again.
    Thanks for any help on this.

    I have to ask why you would want to mix blocking and non-blocking I/O.
    The only reason you would (IMHO) want to use non-blocking I/O is in a highly concurrent system, to increase the maximum load a system can handle.
    The main reason you would want to use blocking I/O rather than non-blocking I/O would be to minimise the latency for a single request.
    Unfortunately, the two don't seem to mix together very well... by switching a thread to blocking, you decrease the latency for a single request, but increase latency for the other requests due to reduced resources available. Similarly, by switching to blocking, you are requiring a dedicated thread for that request, so limiting the number of concurrent requests that can be serviced.
    That is, it seems to me that using both blocking and non-blocking I/O introduces the weaknesses of both into the system, without gaining much of the benefits of either.
    The above aside, the method you gave looks like it would work as you expect, depending on what you are doing with thread creation/delegation. Did your test case work as expected?

  • 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.

Maybe you are looking for

  • Why animated gif not working in webpage designed in fireworks?

    Hi, I have 2 questions. Pl. consider me a novice in this field, started just 2 days ago. 1. I have designed a website page in fireworks cs5, I have added an animated gif in the page and when I preview in browser or export the webpage.png the animated

  • NMH 410 "Remote Access" - Videos Do Not Play

    When accessing my Media Hub from a "remote" location the videos do not play (I only have videos on my Media Hub).  Instead, I get the following error message: Error: Could not play the selected title Windows Media: this media player was detected but

  • IWeb and Photo Album/Slideshows

    My apologies if this topic has been done before. But I didn't find anything specific to answer my question here on the board. For starters, I'm new to iWeb. Actually, aside from a .MAC account I'm new to web design period. I was wondering if someone

  • IPhoto Sharing with Videos?

    Is there any way to share videos stored in iPhoto 9 to another Mac using sharing within iPhoto? All I can see on the other Mac are the photos, the videos don't show up.

  • Camera render / thumbnail media on Mac HD not FW drive

    I note that FCP X seems to be storing files on my MacHD in: user/movies/final cut events/camera render files (and effect browser and "render files") even though I have my Projects and Events on a FW drive. Is this normal?