@Override protected 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); } } if (failure) { key.cancel(); // Some JDK implementations run into an infinite loop without this. close(channel, succeededFuture(channel)); return false; } return true; }
private boolean read(SelectionKey k) { final SctpChannelImpl channel = (SctpChannelImpl) k.attachment(); final ReceiveBufferSizePredictor predictor = channel.getConfig().getReceiveBufferSizePredictor(); final int predictedRecvBufSize = predictor.nextReceiveBufferSize(); boolean messageReceived = false; boolean failure = true; MessageInfo messageInfo = null; ByteBuffer bb = recvBufferPool.acquire(predictedRecvBufSize); try { messageInfo = channel.channel.receive(bb, null, notificationHandler); if (messageInfo != null) { messageReceived = true; if (!messageInfo.isUnordered()) { failure = false; } else { if (logger.isErrorEnabled()) { logger.error("Received unordered SCTP Packet"); } failure = true; } } else { messageReceived = false; failure = false; } } catch (ClosedChannelException e) { // Can happen, and does not need a user attention. } catch (Throwable t) { fireExceptionCaught(channel, t); } if (messageReceived) { bb.flip(); final ChannelBufferFactory bufferFactory = channel.getConfig().getBufferFactory(); final int receivedBytes = bb.remaining(); final ChannelBuffer buffer = bufferFactory.getBuffer(receivedBytes); buffer.setBytes(0, bb); buffer.writerIndex(receivedBytes); recvBufferPool.release(bb); // Update the predictor. predictor.previousReceiveBufferSize(receivedBytes); // Fire the event. fireMessageReceived(channel, new SctpFrame(messageInfo, buffer), messageInfo.address()); } else { recvBufferPool.release(bb); } if (channel.channel.isBlocking() && !messageReceived || failure) { k.cancel(); // Some JDK implementations run into an infinite loop without this. close(channel, succeededFuture(channel)); return false; } return true; }