non blocking sockets and alternatives

Discussion in 'Java' started by conrad, Mar 20, 2009.

  1. conrad

    conrad Guest

    It seems either non-blocking sockets can be used or
    blocking sockets with two threads, one for reading and
    the other for writing. Is this correct?

    My next question is this, I was messing about with
    Java's non blocking sockets and registered the
    read and write operations with the socket channel.

    client.configureBlocking(false);
    Selector selector = Selector.open();
    client.register(selector, SelectionKey.OP_READ |
    SelectionKey.OP_WRITE);

    If a read is set, then I call my read function which chiefly
    does the following(I'm keeping it very simple at the moment
    and will add checks for other kinds of errors later):

    ByteBuffer buffer = ByteBuffer.allocateDirect (1024);
    buffer.clear();

    while((count = socketChannel.read(buffer)) > 0) {
    buffer.flip();
    out.write(buffer);
    buffer.clear();
    }

    What's peculiar is that after reading, when it is ready
    for a write, I call my write function and send data to
    the server:
    ByteBuffer buffer = ByteBuffer.wrap("myusername\r\n".getBytes());
    buffer.flip();
    socketChannel.write(buffer);


    Then, the next read will return what I have written to the server.
    How is that possible? Looking into the use of non-blocking
    sockets more deeply, it seems Java structures the stream
    between client and server by doing the following:
    size_of_data + the_data

    At least, based on some Java I was looking at.
    Could anyone elaborate on this? I clearly need
    a Java book on non-blocking input/output but
    for the meantime would greatly appreciate if
    anyone could clarify the above.

    Thanks.
     
    conrad, Mar 20, 2009
    #1
    1. Advertisements

  2. conrad

    EJP Guest

    Or blocking sockets with +one+ thread if your conversations are
    transactional. Most people do this.
    That's your first mistake. You should only register OP_WRITE when you
    have something to write, and deregister it immediately the data is
    completely written. Otherwise the selector loop spins, because OP_WRITE
    is always ready unless the socket send buffer is full, which is usually
    a transient condition.
    Never ignore the result of a non-blocking write. This loop should be
    written as follows:

    int readCount, writeCount;
    while ((readCount = in.read(buffer)) > 0)
    {
    try
    {
    buffer.flip();
    writeCount = out.write(buffer);
    if (writeCount == 0)
    {
    out.register(selector, SelectionKey,OP_WRITE);
    break;
    }
    }
    finally
    {
    buffer.compact();
    }
    }
    if (readCount < 0)
    in.close();
    I don't think you have to flip after a wrap, but I could be wrong.
    Nope. It just sends the data you sent. Sometimes *applications* prepend
    a size word to a transaction, so you know when you've read it all.
    <shameless plug>
    http://www.telekinesis.com.au/wipv3_6/FundamentalNetworkingInJava.A21
    </shameless plug>
     
    EJP, Mar 20, 2009
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.