non blocking sockets and alternatives

C

conrad

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

EJP

conrad said:
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?

Or blocking sockets with +one+ thread if your conversations are
transactional. Most people do this.
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.

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.
out.write(buffer);

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();
ByteBuffer buffer = ByteBuffer.wrap("myusername\r\n".getBytes());
buffer.flip();

I don't think you have to flip after a wrap, but I could be wrong.
it seems Java structures the stream
between client and server by doing the following:
size_of_data + the_data

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.
I clearly need
a Java book on non-blocking input/output

<shameless plug>
http://www.telekinesis.com.au/wipv3_6/FundamentalNetworkingInJava.A21
</shameless plug>
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top