Help with NIO

X

Xtian.Aguilar.B

I read a lot of NIO concepts in books and internet but I cant find a
good way or explanation of how can I read from Nonbloking I/O.
Some of things that I cant understand:
1. If I have a buffer of size of 1024, and a client send me a first
message how I know when finish the this first message because maybe
he/she can send more messages. Each time the client send messages, they
migth arrive together?
2. If read about state machines to manage the protocol, but I can find
an example, there is an open source project where using NIO?

Thanks a lot.

PD. sorry my english is not so good.
 
G

Gordon Beaton

1. If I have a buffer of size of 1024, and a client send me a first
message how I know when finish the this first message because maybe
he/she can send more messages. Each time the client send messages, they
migth arrive together?

This isn't related to NIO or even Java, it's simply the way TCP works.
Your application needs to deal with the possibility that messages may
arrive in pieces or together with neighbouring messages. There are
various ways to do that, some of them are:

- send the length of the message before the message itself
- use a special character or character sequence to terminate each
message
- send only fixed length messages

/gordon
 
R

Roedy Green

1. If I have a buffer of size of 1024, and a client send me a first
message how I know when finish the this first message because maybe
he/she can send more messages. Each time the client send messages, they
migth arrive together?

A socket is just a stream. The bytes will appear at the other end in
the same order they were put in. If your socket stream is composed of
messages you need some way to tell when one message ends and another
begins.

There are four common techniques.

1. fixed length messages, possibly with a type byte on the front of
each message.

2. messages with a length prefix, or embedded lengths for message
add-ons.

3. reserving some character as an inter-message delimiter.

4. using serialised objects. You let java figure it out.

It is not like the old modem days where you have to resync after a
bout of line noise. You are guaranteed an error free channel.
 
A

AWieminer

1. If I have a buffer of size of 1024, and a client send me a first
This isn't related to NIO or even Java, it's simply the way TCP works.
Your application needs to deal with the possibility that messages may
arrive in pieces or together with neighbouring messages. There are
various ways to do that, some of them are:

- send the length of the message before the message itself
- use a special character or character sequence to terminate each
message
- send only fixed length messages

I have found it easiest to use a terminator byte (#0 NULL for example)
at the end of message packet. If you send string data NULL should be
fine, but sending a binary files it might not work. Binary file may have
a terminator byte as a data byte. I have done only string-based messages
so it has not been a problem yet.

Basicly what I do is this:
* each connection has a private incomingBuffer ByteArrayOutputStream
* I put all incoming bytes to incomingBuffer
* I analyze buffer data during writing and look for NULL terminator
* if terminator is found I take bytes from startOfBuffer to terminator
byte and create a new message object
* message object is added to FIFO taskhandler queue
* all remaining incomingBuffer bytes stays in a buffer until next
terminator byte is found

To make life easier do not overuse threads. Keep most if not all NIO
handling code in a single thread. This will eliminate many nio bugs for
free. You may use a separate thread for message handler, that removes
messages from synchronized fifo queue.

Handling a response writes is another big task. I keep it in a nio
thread as well. Each connection has a private outgoingMessages list. nio
thread takes pending outgoing messages and writes data to the socket.
 
C

Christiansem

thanks folks for your ideas. I'm really glad
I found some code for read from a socketchanel and I would like what
is your opinion about it.

**************** First one ****************
http://www2.sys-con.com/ITSG/virtualcd/Java/archives/0705/schreiber/index.html

//requestLineBuffer is a ByteBuffer
public void readRequest() throws IOException {
try {
if (!requestLineBuffer.hasRemaining()) {
setError(414, "Request URI too long.");
prepareForResponse();
return;
}
socketChannel.read(requestLineBuffer);
if (!isRequestLineRead()) {
return;
}
requestLineBuffer.flip();
byte[] b = new byte[endOfLineIndex];
requestLineBuffer.get(b);
String requestline = new String(b, 0);
StringTokenizer st
= new StringTokenizer(requestline, " \r\n");
String method = st.nextToken();
uri = st.nextToken();
File file = new File(uri.substring(1));
if (st.hasMoreTokens()) {
protocol = st.nextToken();
}
if (!method.equals("GET")) {
setError(405, "Method " + method
+ " is not supported.");
} else if (!file.exists() || file.isDirectory()) {
setError(404, "Resource " + uri
+ " was not found.");
} else if (!file.canRead()) {
setError(403, "Forbidden: " + uri);
} else {
fileLength = file.length();
fileChannel
= new FileInputStream(file).getChannel();
}
prepareForResponse();
} catch (NoSuchElementException nsee) {
// we didn't read enough tokens
setError(400, "Bad request.");
} catch (Exception e) {
// something else went wrong
setError(500, "Internal Server Error.");
prepareForResponse();
e.printStackTrace();
}

**************** Second one ****************
http://www.onjava.com/pub/a/onjava/2004/09/01/nio.html?page=3

/**
* Holds a message that is not fully assembled. This buffer is
fixed-size.
* If it is exceed, an Exception is raised by the decode() method.
*/
private byte[] buffer = new byte[BUFFER_SIZE];
/** Write position on the previous buffer. */
private int pos = 0;

public ByteBuffer decode(ByteBuffer socketBuffer) throws IOException
{
// Reads until the buffer is empty or until a packet
// is fully reassembled.
while (socketBuffer.hasRemaining()) {
// Copies into the temporary buffer
byte b = socketBuffer.get();
try {
buffer[pos] = b;
} catch (IndexOutOfBoundsException e) {
// The buffer has a fixed limit. If this limit is reached, them
// most likely the packet that is being read is corrupt.
e.printStackTrace();
throw new IOException(
"Packet too big. Maximum size allowed: " + BUFFER_SIZE + "
bytes.");
}
pos++;

// Check if it is the final byte of a packet.
if (b == ETX) {
// The current packet is fully reassembled. Return it
byte[] newBuffer = new byte[pos];
System.arraycopy(buffer, 0, newBuffer, 0, pos);
ByteBuffer packetBuffer = ByteBuffer.wrap(newBuffer);
pos = 0;

return packetBuffer;
}
}
// No packet was reassembled. There is not enough data. Wait
// for more data to arrive.
return null;
}

In which of them I could base my producction application, I mean which
is the better option for read from a bytebuffer in nonbloking IO for a
producction application.

Thanks a lot for your time

Bye

PD again sorry for my english.
 

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

Similar Threads

NIO multiplexing + thread pooling 16
NIO UDP and TCP 5
NIO, SocketChannel and packet processing 10
Help 1
JAVA NIO 4
NIO versus NET? 1
Help with Loop 0
Help with Github??? 2

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top