*
* @param key The selection key which contains the Selector registration information.
*/
private boolean read(final SelectionKey key) {
final NioDatagramChannel channel = (NioDatagramChannel) key.attachment();
ReceiveBufferSizePredictor predictor =
channel.getConfig().getReceiveBufferSizePredictor();
final ChannelBufferFactory bufferFactory = channel.getConfig().getBufferFactory();
final DatagramChannel nioChannel = (DatagramChannel) key.channel();
// Allocating a non-direct buffer with a max udp packge size.
// Would using a direct buffer be more efficient or would this negatively
// effect performance, as direct buffer allocation has a higher upfront cost
// where as a ByteBuffer is heap allocated.
final ByteBuffer byteBuffer = ByteBuffer.allocate(
predictor.nextReceiveBufferSize()).order(bufferFactory.getDefaultOrder());
boolean failure = true;
SocketAddress remoteAddress = null;
try {
// Receive from the channel in a non blocking mode. We have already been notified that
// the channel is ready to receive.
remoteAddress = nioChannel.receive(byteBuffer);
failure = false;
} catch (ClosedChannelException e) {
// Can happen, and does not need a user attention.
} catch (Throwable t) {
fireExceptionCaught(channel, t);
}
if (remoteAddress != null) {
// Flip the buffer so that we can wrap it.
byteBuffer.flip();
int readBytes = byteBuffer.remaining();
if (readBytes > 0) {
// Update the predictor.
predictor.previousReceiveBufferSize(readBytes);
// Notify the interested parties about the newly arrived message.
fireMessageReceived(
channel, bufferFactory.getBuffer(byteBuffer), remoteAddress);
}