Search code examples
javanio

Reading data in NIO


I'm trying to write my own NIO server with my custom protocol. As always I put the number of bytes before the actual bytes. Like this:

                   509234
Number of bytes----^|||||----Actual bytes

The problem is when I extracted SelectionKey and got the SocketChannel like this:

SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(128);
int numRead = channel.read(buffer); // <---- 4, not 5

I can potentially receive the number of bytes: 5 and the actual bytes 0923, where the last byte 4 is not yet available to read from the channel. But for processing I need all bytes.

How to deal with such a situation? Do I need to store the SocketChannel somewhere (e.g. Map<SocketChannel, byte[]>) to keep track of it? And when the rest of data is available to read from the channel I will add the data to the Map


Solution

  • You need a ByteBuffer per channel. When it's readable, read into it, and when you have a complete message in there, process it.

    You can associate the buffer with the channel via a Map, but it's simpler to use the key attachment facility.