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