Example usage for java.nio.channels SelectionKey isReadable

List of usage examples for java.nio.channels SelectionKey isReadable

Introduction

In this page you can find the example usage for java.nio.channels SelectionKey isReadable.

Prototype

public final boolean isReadable() 

Source Link

Document

Tests whether this key's channel is ready for reading.

Usage

From source file:eu.stratosphere.nephele.taskmanager.bytebuffered.IncomingConnectionThread.java

@Override
public void run() {

    while (!this.isInterrupted()) {

        synchronized (this.pendingReadEventSubscribeRequests) {
            while (!this.pendingReadEventSubscribeRequests.isEmpty()) {
                final SelectionKey key = this.pendingReadEventSubscribeRequests.poll();
                final IncomingConnection incomingConnection = (IncomingConnection) key.attachment();
                final SocketChannel socketChannel = (SocketChannel) key.channel();

                try {
                    final SelectionKey newKey = socketChannel.register(this.selector, SelectionKey.OP_READ);
                    newKey.attach(incomingConnection);
                } catch (ClosedChannelException e) {
                    incomingConnection.reportTransmissionProblem(key, e);
                }/*from   w  ww .ja va  2  s .  co  m*/
            }
        }

        try {
            this.selector.select(500);
        } catch (IOException e) {
            LOG.error(e);
        }

        final Iterator<SelectionKey> iter = this.selector.selectedKeys().iterator();

        while (iter.hasNext()) {
            final SelectionKey key = iter.next();

            iter.remove();
            if (key.isValid()) {
                if (key.isReadable()) {
                    doRead(key);
                } else if (key.isAcceptable()) {
                    doAccept(key);
                } else {
                    LOG.error("Unknown key: " + key);
                }
            } else {
                LOG.error("Received invalid key: " + key);
            }
        }
    }

    // Do cleanup, if necessary
    if (this.listeningSocket != null) {
        try {
            this.listeningSocket.close();
        } catch (IOException ioe) {
            // Actually, we can ignore this exception
            LOG.debug(ioe);
        }
    }

    // Finally, close the selector
    try {
        this.selector.close();
    } catch (IOException ioe) {
        LOG.debug(StringUtils.stringifyException(ioe));
    }
}

From source file:com.openteach.diamond.network.waverider.network.DefaultNetWorkClient.java

/**
 * ?, ?, ?, ??/*from   www  .j  a  va  2  s. com*/
 * @throws IOException
 * @throws InterruptedException
 */
private void dispatch() throws IOException, InterruptedException {
    logger.debug("try dispatch");
    SelectionKey key = null;
    key = opsChangeRequest.getChannel().keyFor(selector);
    if (key != null) {
        if ((opsChangeRequest.getOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
            // 
            key.interestOps(SelectionKey.OP_WRITE);
            opsChangeRequest.clearOps(SelectionKey.OP_WRITE);
        } else if ((opsChangeRequest.getOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
            key.interestOps(SelectionKey.OP_READ);
            opsChangeRequest.clearOps(SelectionKey.OP_READ);
        }
    }

    // ?,  
    isWeakuped.set(false);
    if (selector.select(WaveriderConfig.WAVERIDER_DEFAULT_NETWORK_TIME_OUT) <= 0) {
        return;
    }

    // ?
    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    while (iterator.hasNext()) {
        key = (SelectionKey) iterator.next();
        iterator.remove();
        if (!key.isValid()) {
            continue;
        } else if (key.isReadable()) {
            onRead(key);
        } else if (key.isWritable()) {
            onWrite(key);
        }
    }
}

From source file:com.openteach.diamond.network.waverider.network.DefaultNetWorkServer.java

private void dispatch() throws IOException {
    logger.debug("try dispatch");
    SelectionKey key = null;
    for (SocketChannelOPSChangeRequest request : opsChangeRequstMap.values()) {
        key = request.getChannel().keyFor(selector);
        if (key != null) {
            // /*  ww w.  j  a v a 2s  .  co m*/
            if ((request.getOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) {
                key.interestOps(SelectionKey.OP_WRITE);
                request.clearOps(SelectionKey.OP_WRITE);
            } else if ((request.getOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
                key.interestOps(SelectionKey.OP_READ);
                request.clearOps(SelectionKey.OP_READ);
            }
        }
    }

    isWeakuped.set(false);
    if (selector.select(WaveriderConfig.WAVERIDER_DEFAULT_NETWORK_TIME_OUT) <= 0) {
        return;
    }

    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    while (iterator.hasNext()) {
        key = (SelectionKey) iterator.next();
        iterator.remove();
        try {
            if (!key.isValid()) {
                continue;
            } else if (key.isAcceptable()) {
                onAccept(key);
            } else if (key.isReadable()) {
                //readerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_READ));
                onRead(key);
            } else if (key.isWritable()) {
                //writerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_WRITE));
                onWrite(key);
            }
        } catch (IOException e) {
            // 
            opsChangeRequstMap.remove((SocketChannel) key.channel());
            Session session = (Session) key.attachment();
            if (session != null) {
                session.onException(e);
                // Session
                sessionManager.freeSession(session);
            }
            key.cancel();
            key.channel().close();
            e.printStackTrace();
            logger.error("OOPSException", e);
        }
    }
}

From source file:jp.queuelinker.system.net.SelectorThread.java

@Override
public void run() {
    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
    // I believe the inner try-catches does not cause overhead.
    // http://stackoverflow.com/questions/141560/
    long sendCount = 0;

    SocketChannel currentChannel;
    SelectionKey key = null;
    while (true) {
        try {/*from w  w w .  j  a  v a 2 s .c  om*/
            selector.select();
            // selector.selectNow();
        } catch (ClosedSelectorException e) {
            logger.fatal("BUG: The selector is closed.");
            return;
        } catch (IOException e) {
            logger.fatal("An IOException occured while calling select().");
            // Fatal Error. Notify the error to the users and leave the matter to them.
            for (ChannelState state : channels) {
                state.callBack.fatalError();
            }
            return;
        }

        if (!requests.isEmpty()) {
            handleRequest();
            continue;
        }

        if (stopRequested) {
            return;
        }

        Set<SelectionKey> keys = selector.selectedKeys();

        Iterator<SelectionKey> iter = keys.iterator();
        iter_loop: while (iter.hasNext()) {
            key = iter.next();
            iter.remove(); // Required. Don't remove.

            if (key.isReadable()) {
                currentChannel = (SocketChannel) key.channel();
                final ChannelState state = (ChannelState) key.attachment();

                int valid;
                try {
                    valid = currentChannel.read(buffer);
                } catch (IOException e) {
                    logger.warn("An IOException happened while reading from a channel.");
                    state.callBack.exceptionOccured(state.channelId, state.attachment);
                    key.cancel();
                    continue;
                }
                if (valid == -1) {
                    // Normal socket close?
                    state.callBack.exceptionOccured(state.channelId, state.attachment);
                    // cleanUpChannel(state.channelId);
                    key.cancel();
                    continue;
                }

                buffer.rewind();
                if (state.callBack.receive(state.channelId, buffer, valid, state.attachment) == false) {
                    state.key.interestOps(state.key.interestOps() & ~SelectionKey.OP_READ);
                }
                buffer.clear();
            } else if (key.isWritable()) {
                currentChannel = (SocketChannel) key.channel();
                final ChannelState state = (ChannelState) key.attachment();

                while (state.sendBuffer.readableSize() < WRITE_SIZE) {
                    ByteBuffer newBuffer = state.callBack.send(state.channelId, state.attachment);
                    if (newBuffer != null) {
                        state.sendBuffer.write(newBuffer);
                        if (++sendCount % 50000 == 0) {
                            logger.info("Send Count: " + sendCount);
                        }
                    } else if (state.sendBuffer.readableSize() == 0) {
                        key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
                        continue iter_loop;
                    } else {
                        break;
                    }
                }

                final int available = state.sendBuffer.readableSize();
                if (available >= WRITE_SIZE || ++state.noopCount >= HEURISTIC_WAIT) {
                    int done;
                    try {
                        done = currentChannel.write(state.sendBuffer.getByteBuffer());
                    } catch (IOException e) {
                        logger.warn("An IOException occured while writing to a channel.");
                        state.callBack.exceptionOccured(state.channelId, state.attachment);
                        key.cancel();
                        continue;
                    }
                    if (done < available) {
                        state.sendBuffer.rollback(available - done);
                    }
                    state.sendBuffer.compact();
                    state.noopCount = 0;
                }
            } else if (key.isAcceptable()) {
                ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                ChannelState state = (ChannelState) key.attachment();
                SocketChannel socketChannel;
                try {
                    socketChannel = channel.accept();
                    socketChannel.configureBlocking(false);
                } catch (IOException e) {
                    continue; // Do nothing.
                }
                state.callBack.newConnection(state.channelId, socketChannel, state.attachment);
            }
        }
    }
}

From source file:Proxy.java

void _handleConnection(final SocketChannel in_channel, final SocketChannel out_channel) throws Exception {
    executor.execute(new Runnable() {
        public void run() {
            Selector sel = null;//from w w  w  . j  a  v a2 s  .  co m
            SocketChannel tmp;
            Set ready_keys;
            SelectionKey key;
            ByteBuffer transfer_buf = ByteBuffer.allocate(BUFSIZE);

            try {
                sel = Selector.open();
                in_channel.configureBlocking(false);
                out_channel.configureBlocking(false);
                in_channel.register(sel, SelectionKey.OP_READ);
                out_channel.register(sel, SelectionKey.OP_READ);

                while (sel.select() > 0) {
                    ready_keys = sel.selectedKeys();
                    for (Iterator it = ready_keys.iterator(); it.hasNext();) {
                        key = (SelectionKey) it.next();
                        it.remove(); // remove current entry (why ?)
                        tmp = (SocketChannel) key.channel();
                        if (tmp == null) {
                            log("Proxy._handleConnection()", "attachment is null, continuing");
                            continue;
                        }
                        if (key.isReadable()) { // data is available to be read from tmp
                            if (tmp == in_channel) {
                                // read all data from in_channel and forward it to out_channel (request)
                                if (relay(tmp, out_channel, transfer_buf) == false)
                                    return;
                            }
                            if (tmp == out_channel) {
                                // read all data from out_channel and forward it 
                                // to in_channel (response)
                                if (relay(tmp, in_channel, transfer_buf) == false)
                                    return;
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                close(sel, in_channel, out_channel);
            }
        }
    });
}

From source file:x10.x10rt.yarn.ApplicationMaster.java

protected void handleX10() {
    // handle X10 place requests
    Iterator<SelectionKey> events = null;
    while (running) {
        try {/* w  w w  .  j  ava  2s. c om*/
            SelectionKey key;
            // check for previously unhandled events
            if (events != null && events.hasNext()) {
                key = events.next();
                events.remove();
            } else if (selector.select() == 0) // check for new events
                continue; // nothing to process, go back and block on select again
            else { // select returned some events
                events = selector.selectedKeys().iterator();
                key = events.next();
                events.remove();
            }

            // process the selectionkey
            if (key.isAcceptable()) {
                LOG.info("New connection from X10 detected");
                // accept any connections on the server socket, and look for things to read from it
                ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                SocketChannel sc = ssc.accept();
                sc.configureBlocking(false);
                sc.register(selector, SelectionKey.OP_READ);
            }
            if (key.isReadable()) {
                SocketChannel sc = (SocketChannel) key.channel();

                ByteBuffer incomingMsg;
                if (pendingReads.containsKey(sc))
                    incomingMsg = pendingReads.remove(sc);
                else
                    incomingMsg = ByteBuffer.allocateDirect(headerLength).order(ByteOrder.nativeOrder());

                LOG.info("Reading message from X10");
                try {
                    if (sc.read(incomingMsg) == -1) {
                        // socket closed
                        sc.close();
                        key.cancel();
                        pendingReads.remove(sc);
                    } else if (incomingMsg.hasRemaining()) {
                        LOG.info("Message header partially read. " + incomingMsg.remaining()
                                + " bytes remaining");
                        pendingReads.put(sc, incomingMsg);
                    } else { // buffer is full
                        if (incomingMsg.capacity() == headerLength) {
                            // check to see if there is a body associated with this message header
                            int datalen = incomingMsg.getInt(headerLength - 4);
                            //System.err.println("Byte order is "+incomingMsg.order()+" datalen="+datalen);
                            if (datalen == 0)
                                processMessage(incomingMsg, sc);
                            else { // create a larger array to hold the header+body
                                ByteBuffer newBuffer = ByteBuffer.allocateDirect(headerLength + datalen)
                                        .order(ByteOrder.nativeOrder());
                                incomingMsg.rewind();
                                newBuffer.put(incomingMsg);
                                incomingMsg = newBuffer;
                                sc.read(incomingMsg); // read in the body, if available
                                if (incomingMsg.hasRemaining()) {
                                    LOG.info("Message partially read. " + incomingMsg.remaining()
                                            + " bytes remaining");
                                    pendingReads.put(sc, incomingMsg);
                                } else
                                    processMessage(incomingMsg, sc);
                            }
                        }
                    }
                } catch (IOException e) {
                    LOG.warn("Error reading in message from socket channel", e);
                }
            }
        } catch (IOException e) {
            LOG.warn("Error handling X10 links", e);
        }
    }
}

From source file:com.voxbone.kelpie.Session.java

public void run() {
    Selector sel = null;//  ww w.j  a  v a  2 s  .com

    logger.info("[[" + internalCallId + "]] Session thread started: " + this.socketChannel.socket().toString());

    try {
        sel = SelectorProvider.provider().openSelector();
        socketChannel.register(sel, SelectionKey.OP_READ, this);

        while (true) {
            if (sel.select() >= 0) {
                Iterator<SelectionKey> itr = sel.selectedKeys().iterator();
                while (itr.hasNext()) {
                    SelectionKey key = itr.next();
                    itr.remove();
                    if (key.isReadable()) {
                        this.execute();
                    }
                }
            } else {
                logger.error("[[" + internalCallId + "]] Select returned error");
            }
            if (conn.getCurrentStatus().isDisconnected()) {
                break;
            }
        }

        logger.info("[[" + internalCallId + "]] Session Connection finished: "
                + this.socketChannel.socket().toString());
        sel.close();
    } catch (IOException e) {
        logger.error("[[" + internalCallId + "]] Error in xmpp session thread", e);
    } catch (StreamException e) {
        logger.error("[[" + internalCallId + "]] Error in xmpp session thread", e);
    } catch (Exception e) {
        logger.error("[[" + internalCallId + "]] Error in xmpp session thread", e);
    } finally {
        try {
            if (sel != null) {
                sel.close();
            }
        } catch (IOException e) {
            // we are dead already, RIP
        }
    }

    // make sure the connection is closed
    try {
        conn.close();
        conn.disconnect();
        try {
            socketChannel.socket().shutdownInput();
        } catch (IOException e) {
            // ignore
        }
        try {
            socketChannel.socket().shutdownOutput();
        } catch (IOException e) {
            // ignore
        }
        try {
            socketChannel.close();
        } catch (IOException e) {
            // ignore
        }
    } catch (StreamException e) {
        logger.error("[[" + internalCallId + "]] Problem closing stream", e);
    }
}

From source file:org.eclipsetrader.directa.internal.core.BrokerConnector.java

@Override
public void run() {
    Selector socketSelector;/* w  w w  . j a va 2 s . c o  m*/
    ByteBuffer dst = ByteBuffer.wrap(new byte[2048]);
    List<Position> positions = new ArrayList<Position>();

    try {
        // Create a non-blocking socket channel
        socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);

        socketChannel.socket().setReceiveBufferSize(32768);
        socketChannel.socket().setSoLinger(true, 1);
        socketChannel.socket().setSoTimeout(0x15f90);
        socketChannel.socket().setReuseAddress(true);

        // Kick off connection establishment
        socketChannel.connect(new InetSocketAddress(server, port));

        // Create a new selector
        socketSelector = SelectorProvider.provider().openSelector();

        // Register the server socket channel, indicating an interest in
        // accepting new connections
        socketChannel.register(socketSelector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
    } catch (Exception e) {
        Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error connecting to orders monitor", //$NON-NLS-1$
                e);
        Activator.log(status);
        return;
    }

    for (;;) {
        try {
            if (socketSelector.select(30 * 1000) == 0) {
                logger.trace(">" + HEARTBEAT); //$NON-NLS-1$
                socketChannel.write(ByteBuffer.wrap(new String(HEARTBEAT + "\r\n").getBytes())); //$NON-NLS-1$
            }
        } catch (Exception e) {
            break;
        }

        // Iterate over the set of keys for which events are available
        Iterator<SelectionKey> selectedKeys = socketSelector.selectedKeys().iterator();
        while (selectedKeys.hasNext()) {
            SelectionKey key = selectedKeys.next();
            selectedKeys.remove();

            if (!key.isValid()) {
                continue;
            }

            try {
                // Check what event is available and deal with it
                if (key.isConnectable()) {
                    // Finish the connection. If the connection operation failed
                    // this will raise an IOException.
                    try {
                        socketChannel.finishConnect();
                    } catch (IOException e) {
                        // Cancel the channel's registration with our selector
                        key.cancel();
                        return;
                    }

                    // Register an interest in writing on this channel
                    key.interestOps(SelectionKey.OP_WRITE);
                }
                if (key.isWritable()) {
                    logger.trace(">" + LOGIN + WebConnector.getInstance().getUser()); //$NON-NLS-1$
                    socketChannel.write(ByteBuffer.wrap(
                            new String(LOGIN + WebConnector.getInstance().getUser() + "\r\n").getBytes())); //$NON-NLS-1$

                    // Register an interest in reading on this channel
                    key.interestOps(SelectionKey.OP_READ);
                }
                if (key.isReadable()) {
                    dst.clear();
                    int readed = socketChannel.read(dst);
                    if (readed > 0) {
                        String[] s = new String(dst.array(), 0, readed).split("\r\n"); //$NON-NLS-1$
                        for (int i = 0; i < s.length; i++) {
                            logger.trace("<" + s[i]); //$NON-NLS-1$

                            if (s[i].endsWith(";" + WebConnector.getInstance().getUser() + ";")) { //$NON-NLS-1$ //$NON-NLS-2$
                                logger.trace(">" + UNKNOWN70); //$NON-NLS-1$
                                socketChannel.write(ByteBuffer.wrap(new String(UNKNOWN70 + "\r\n").getBytes())); //$NON-NLS-1$
                                logger.trace(">" + UNKNOWN55); //$NON-NLS-1$
                                socketChannel.write(ByteBuffer.wrap(new String(UNKNOWN55 + "\r\n").getBytes())); //$NON-NLS-1$
                            }

                            if (s[i].indexOf(";6;5;") != -1 || s[i].indexOf(";8;0;") != -1) { //$NON-NLS-1$ //$NON-NLS-2$
                                try {
                                    OrderMonitor monitor = parseOrderLine(s[i]);

                                    OrderDelta[] delta;
                                    synchronized (orders) {
                                        if (!orders.contains(monitor)) {
                                            orders.add(monitor);
                                            delta = new OrderDelta[] {
                                                    new OrderDelta(OrderDelta.KIND_ADDED, monitor) };
                                        } else {
                                            delta = new OrderDelta[] {
                                                    new OrderDelta(OrderDelta.KIND_UPDATED, monitor) };
                                        }
                                    }
                                    fireUpdateNotifications(delta);

                                    if (monitor.getFilledQuantity() != null
                                            && monitor.getAveragePrice() != null) {
                                        Account account = WebConnector.getInstance().getAccount();
                                        account.updatePosition(monitor);
                                    }
                                } catch (ParseException e) {
                                    Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                                            "Error parsing line: " + s[i], e); //$NON-NLS-1$
                                    Activator.log(status);
                                }
                            }
                            if (s[i].indexOf(";6;0;") != -1) { //$NON-NLS-1$
                                updateStatusLine(s[i]);
                            }
                            if (s[i].indexOf(";7;0;") != -1) { //$NON-NLS-1$
                                try {
                                    positions.add(new Position(s[i]));
                                } catch (Exception e) {
                                    Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                                            "Error parsing line: " + s[i], e); //$NON-NLS-1$
                                    Activator.log(status);
                                }
                            }
                            if (s[i].indexOf(";7;9;") != -1) { //$NON-NLS-1$
                                Account account = WebConnector.getInstance().getAccount();
                                account.setPositions(positions.toArray(new Position[positions.size()]));
                                positions.clear();
                            }
                        }
                    }
                }
            } catch (Exception e) {
                Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Connection error", e); //$NON-NLS-1$
                Activator.log(status);
            }
        }
    }
}

From source file:org.openhab.binding.tcp.AbstractDatagramChannelBinding.java

/**
 * @{inheritDoc}//from  w w  w  . j  a va 2  s . c  om
 */
@Override
protected void execute() {

    // Cycle through the Items and setup channels if required
    for (P provider : providers) {
        for (String itemName : provider.getItemNames()) {
            for (Command aCommand : ((P) provider).getAllCommands(itemName)) {

                String remoteHost = ((P) provider).getHost(itemName, aCommand);
                String remotePort = ((P) provider).getPortAsString(itemName, aCommand);
                Direction direction = ((P) provider).getDirection(itemName, aCommand);

                InetSocketAddress remoteAddress = null;
                if (!(remoteHost.equals("*") || remotePort.equals("*"))) {
                    remoteAddress = new InetSocketAddress(remoteHost, Integer.parseInt(remotePort));
                }

                Channel newChannel = null;
                Channel existingChannel = null;

                if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) {
                    newChannel = new Channel(itemName, aCommand, remoteHost, remotePort,
                            ((P) provider).getDirection(itemName, aCommand), false, null, false, null);
                    existingChannel = channels.get(itemName, aCommand, direction, remoteHost, remotePort);
                } else {
                    newChannel = new Channel(itemName, aCommand, remoteAddress,
                            ((P) provider).getDirection(itemName, aCommand), false, null, false, null);
                    existingChannel = channels.get(itemName, aCommand, direction, remoteAddress);
                }

                if (existingChannel == null) {
                    if (direction == Direction.IN) {

                        boolean assigned = false;

                        if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) {
                            logger.warn(
                                    "When using address masks we will not verify if we are already listening to similar incoming connections");
                            logger.info("We will accept data coming from the remote end {}:{}", remoteHost,
                                    remotePort);
                        } else {
                            if (channels.contains(itemName, aCommand, Direction.IN, remoteAddress)) {
                                logger.warn("We already listen for incoming connections from {}",
                                        remoteAddress);
                            } else {

                                if (itemShareChannels) {
                                    Channel firstChannel = channels.getFirstServed(itemName, direction,
                                            remoteAddress);
                                    if (firstChannel != null) {
                                        newChannel.channel = firstChannel.channel;
                                        assigned = true;
                                    }
                                }

                                if (bindingShareChannels) {
                                    Channel firstChannel = channels.getFirstServed(direction, remoteAddress);
                                    if (firstChannel != null) {
                                        newChannel.channel = firstChannel.channel;
                                        assigned = true;
                                    }
                                }

                                if (directionsShareChannels) {
                                    Channel firstChannel = channels.getFirstServed(remoteAddress);
                                    if (firstChannel != null) {
                                        newChannel.channel = firstChannel.channel;
                                        assigned = true;
                                    }
                                }
                            }
                        }

                        if (!assigned) {
                            newChannel.channel = listenerChannel;
                        }

                        if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) {
                            logger.info("We will accept data coming from the remote end with mask {}:{}",
                                    remoteHost, remotePort);
                        } else {
                            logger.info("We will accept data coming from the remote end {}", remoteAddress);
                        }
                        logger.debug("Setting up the inbound channel {}", newChannel);
                        channels.add(newChannel);

                    } else if (direction == Direction.OUT) {

                        boolean assigned = false;

                        if (useAddressMask && (remoteHost.equals("*") || remotePort.equals("*"))) {
                            logger.error(
                                    "We do not accept outgoing connections for Items that do use address masks");
                        } else {

                            channels.add(newChannel);

                            if (newChannel.channel == null) {

                                if (itemShareChannels) {
                                    Channel firstChannel = channels.getFirstServed(itemName, direction,
                                            remoteAddress);
                                    if (firstChannel != null) {
                                        newChannel.channel = firstChannel.channel;
                                        assigned = true;
                                    }
                                }

                                if (bindingShareChannels) {
                                    Channel firstChannel = channels.getFirstServed(direction, remoteAddress);
                                    if (firstChannel != null) {
                                        newChannel.channel = firstChannel.channel;
                                        assigned = true;
                                    }
                                }

                                // I think it is better not to share incoming connections with outgoing connections (in the case of the 
                                // UDP binding)

                                //               if(directionsShareChannels) {
                                //                  Channel firstChannel = channels.getFirstServed(remoteAddress);
                                //                  if(firstChannel != null) {
                                //                     newChannel.channel = firstChannel.channel;
                                //                     assigned = true;
                                //                  }               
                                //   

                                if (assigned) {
                                    logger.debug("Setting up the outbound assigned channel {} ", newChannel);
                                }
                            }

                            synchronized (this) {

                                if (!assigned || newChannel.channel == null) {

                                    DatagramChannel newDatagramChannel = null;
                                    try {
                                        newDatagramChannel = DatagramChannel.open();
                                    } catch (IOException e2) {
                                        logger.error("An exception occurred while opening a channel: {}",
                                                e2.getMessage());
                                    }

                                    try {
                                        newDatagramChannel.configureBlocking(false);
                                        //setKeepAlive(true);
                                    } catch (IOException e) {
                                        logger.error("An exception occurred while configuring a channel: {}",
                                                e.getMessage());
                                    }

                                    synchronized (selector) {
                                        selector.wakeup();
                                        try {
                                            newDatagramChannel.register(selector,
                                                    newDatagramChannel.validOps());
                                        } catch (ClosedChannelException e1) {
                                            logger.error(
                                                    "An exception occurred while registering a selector: {}",
                                                    e1.getMessage());
                                        }
                                    }

                                    newChannel.channel = newDatagramChannel;
                                    logger.debug("Setting up the outbound channel {}", newChannel);

                                    try {
                                        logger.info("'Connecting' the channel {} ", newChannel);
                                        newDatagramChannel.connect(remoteAddress);
                                    } catch (IOException e) {
                                        logger.error("An exception occurred while connecting a channel: {}",
                                                e.getMessage());
                                    }
                                } else {
                                    logger.info("There is already an active channel {} for the remote end {}",
                                            newChannel.channel, newChannel.remote);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // Check on channels for which we have to process data
    synchronized (selector) {
        try {
            // Wait for an event
            selector.selectNow();
        } catch (IOException e) {
            logger.error("An exception occurred while Selecting ({})", e.getMessage());
        }
    }

    // Get list of selection keys with pending events
    Iterator<SelectionKey> it = selector.selectedKeys().iterator();

    // Process each key at a time
    while (it.hasNext()) {
        SelectionKey selKey = (SelectionKey) it.next();
        it.remove();

        if (selKey.isValid()) {
            DatagramChannel theDatagramChannel = (DatagramChannel) selKey.channel();
            Channel theChannel = channels.get(theDatagramChannel);

            if (selKey.isReadable()) {
                InetSocketAddress clientAddress = null;
                ByteBuffer readBuffer = ByteBuffer.allocate(maximumBufferSize);
                int numberBytesRead = 0;
                boolean error = false;

                if (selKey == listenerKey) {
                    try {
                        clientAddress = (InetSocketAddress) theDatagramChannel.receive(readBuffer);
                        logger.debug("Received {} on the listener port from {}", new String(readBuffer.array()),
                                clientAddress);
                        numberBytesRead = readBuffer.position();
                    } catch (Exception e) {
                        error = true;
                    }

                } else {

                    try {
                        //TODO: Additional code to split readBuffer in multiple parts, in case the data send by the remote end is not correctly fragemented. Could be handed of to implementation class if for example, the buffer needs to be split based on a special character like line feed or carriage return
                        numberBytesRead = theDatagramChannel.read(readBuffer);
                        logger.debug("Received {} bytes ({}) on the channel {}->{}",
                                new Object[] { numberBytesRead, new String(readBuffer.array()),
                                        theDatagramChannel.getLocalAddress(),
                                        theDatagramChannel.getRemoteAddress() });
                    } catch (NotYetConnectedException e) {
                        try {
                            logger.warn("The channel for {} has no connection pending ({})",
                                    theDatagramChannel.getRemoteAddress(), e.getMessage());
                        } catch (IOException e1) {
                            logger.error(
                                    "An exception occurred while getting the remote address of channel {} ({})",
                                    theDatagramChannel, e1.getMessage());
                        }
                        error = true;
                    } catch (IOException e) {
                        // If some other I/O error occurs
                        try {
                            logger.warn("The channel for {} has encountered an unknown IO Exception: {}",
                                    theDatagramChannel.getRemoteAddress(), e.getMessage());
                        } catch (IOException e1) {
                            logger.error(
                                    "An exception occurred while getting the remote address of channel {} ({})",
                                    theDatagramChannel, e1.getMessage());
                        }
                        error = true;
                    }
                }

                if (numberBytesRead == -1) {
                    try {
                        if (selKey != listenerKey) {
                            theDatagramChannel.close();
                        }
                    } catch (IOException e) {
                        try {
                            logger.warn("The channel for {} is closed ({})",
                                    theDatagramChannel.getRemoteAddress(), e.getMessage());
                        } catch (IOException e1) {
                            logger.error(
                                    "An exception occurred while getting the remote address of channel {} ({})",
                                    theDatagramChannel, e1.getMessage());
                        }
                    }
                    error = true;
                }

                if (error) {
                    if (selKey != listenerKey) {

                        Scheduler scheduler = null;
                        try {
                            scheduler = StdSchedulerFactory.getDefaultScheduler();
                        } catch (SchedulerException e1) {
                            logger.error("An exception occurred while getting the Quartz scheduler: {}",
                                    e1.getMessage());
                        }

                        JobDataMap map = new JobDataMap();
                        map.put("Channel", theChannel);
                        map.put("Binding", this);

                        JobDetail job = null;
                        Trigger trigger = null;

                        job = newJob(ReconnectJob.class)
                                .withIdentity(Integer.toHexString(hashCode()) + "-Reconnect-"
                                        + Long.toString(System.currentTimeMillis()), this.toString())
                                .usingJobData(map).build();

                        trigger = newTrigger()
                                .withIdentity(Integer.toHexString(hashCode()) + "-Reconnect-"
                                        + Long.toString(System.currentTimeMillis()), this.toString())
                                .startAt(futureDate(reconnectInterval, IntervalUnit.SECOND)).build();

                        try {
                            if (job != null && trigger != null && selKey != listenerKey) {
                                if (!theChannel.isReconnecting) {
                                    channels.setAllReconnecting(theDatagramChannel, true);
                                    scheduler.scheduleJob(job, trigger);
                                }
                            }
                        } catch (SchedulerException e) {
                            logger.error(
                                    "An exception occurred while scheduling a job with the Quartz Scheduler {}",
                                    e.getMessage());
                        }
                    }

                } else {

                    ArrayList<Channel> channelsToServe = new ArrayList<Channel>();

                    if (selKey == listenerKey) {
                        channelsToServe = channels.getAll(Direction.IN, clientAddress);
                        if (channelsToServe.size() == 0) {
                            logger.warn(
                                    "Received data {} from an undefined remote end {}. We will not process it",
                                    new String(readBuffer.array()), clientAddress);
                        }
                    } else {
                        channelsToServe = channels.getAll(theDatagramChannel);
                    }

                    if (channelsToServe.size() > 0) {

                        readBuffer.flip();

                        if (channels.isBlocking(theDatagramChannel)) {
                            // if we are in a blocking operation, we get are now finished and we have to reset the flag. The read buffer will be returned to the instance
                            // that initiated the write opreation - it has to parse the buffer itself

                            //find the Channel with this DGC that is holding a Blocking flag
                            theChannel = channels.getBlocking(theDatagramChannel);
                            theChannel.buffer = readBuffer;

                        } else {
                            for (Channel aChannel : channelsToServe) {
                                if (useAddressMask) {
                                    aChannel.lastRemote = clientAddress;
                                }
                                // if not, then we parse the buffer as ususal
                                parseChanneledBuffer(aChannel, readBuffer);
                            }
                        }
                    } else {
                        try {
                            if (selKey == listenerKey) {
                                logger.warn(
                                        "No channel is active or defined for the data we received from {}. It will be discarded.",
                                        clientAddress);
                            } else {
                                logger.warn(
                                        "No channel is active or defined for the data we received from {}. It will be discarded.",
                                        theDatagramChannel.getRemoteAddress());
                            }
                        } catch (IOException e) {
                            logger.error(
                                    "An exception occurred while getting the remote address of channel {} ({})",
                                    theDatagramChannel, e.getMessage());
                        }
                    }
                }
            } else if (selKey.isWritable()) {

                WriteBufferElement theElement = null;

                if (selKey == listenerKey) {
                    Iterator<WriteBufferElement> iterator = writeQueue.iterator();
                    while (iterator.hasNext()) {
                        WriteBufferElement anElement = iterator.next();
                        if (anElement.channel.channel.equals(listenerChannel)) {
                            theElement = anElement;
                            break;
                        }
                    }
                }

                //check if any of the Channel using the DatagramChannel is blocking the DGC in a R/W operation
                boolean isBlocking = channels.isBlocking(theDatagramChannel);

                if (isBlocking) {
                    // if this channel is already flagged as being in a blocked write/read operation, we skip this selKey
                } else {

                    if (selKey != listenerKey) {
                        Iterator<WriteBufferElement> iterator = writeQueue.iterator();
                        while (iterator.hasNext()) {
                            WriteBufferElement anElement = iterator.next();
                            if (anElement.channel.channel.equals(theDatagramChannel)) {
                                theElement = anElement;
                                break;
                            }
                        }
                    }

                    if (theElement != null && theElement.buffer != null) {

                        logger.debug("Picked {} from the queue", theElement);

                        if (theElement.isBlocking) {
                            theElement.channel.isBlocking = true;
                        }

                        boolean error = false;

                        theElement.buffer.rewind();

                        if (selKey == listenerKey) {
                            try {
                                if (useAddressMask && theElement.channel.remote == null) {
                                    if (theElement.channel.lastRemote != null) {
                                        logger.debug(
                                                "Sending {} for the masked inbound channel {}:{} to the remote address {}",
                                                new Object[] { new String(theElement.buffer.array()),
                                                        theElement.channel.host, theElement.channel.port,
                                                        theElement.channel.lastRemote });
                                        listenerChannel.send(theElement.buffer, theElement.channel.lastRemote);
                                    } else {
                                        logger.warn("I do not know where to send the data {}",
                                                new String(theElement.buffer.array()));
                                    }
                                } else {
                                    logger.debug(
                                            "Sending {} for the inbound channel {}:{} to the remote address {}",
                                            new Object[] { new String(theElement.buffer.array()),
                                                    theElement.channel.host, theElement.channel.port,
                                                    theElement.channel.remote });
                                    listenerChannel.send(theElement.buffer, theElement.channel.remote);
                                }
                            } catch (IOException e) {
                                if (theElement.channel.lastRemote != null) {
                                    logger.error(
                                            "An exception occurred while sending data to the remote end {} ({})",
                                            theElement.channel.lastRemote, e.getMessage());
                                } else {
                                    logger.error(
                                            "An exception occurred while sending data to the remote end {} ({})",
                                            theElement.channel.remote, e.getMessage());
                                }
                            }
                        } else {

                            try {
                                logger.debug(
                                        "Sending {} for the outbound channel {}:{} to the remote address {}",
                                        new Object[] { new String(theElement.buffer.array()),
                                                theElement.channel.host, theElement.channel.port,
                                                theElement.channel.remote });
                                theDatagramChannel.write(theElement.buffer);
                            } catch (NotYetConnectedException e) {
                                logger.warn("The channel for {} has no connection pending ({})",
                                        theElement.channel.remote, e.getMessage());
                                error = true;
                            } catch (ClosedChannelException e) {
                                // If some other I/O error occurs
                                logger.warn("The channel for {} is closed ({})", theElement.channel.remote,
                                        e.getMessage());
                                error = true;
                            } catch (IOException e) {
                                // If some other I/O error occurs
                                logger.warn("The channel for {} has encountered an unknown IO Exception: {}",
                                        theElement.channel.remote, e.getMessage());
                                error = true;
                            }
                        }

                        if (error) {

                            if (selKey != listenerKey) {

                                Scheduler scheduler = null;
                                try {
                                    scheduler = StdSchedulerFactory.getDefaultScheduler();
                                } catch (SchedulerException e1) {
                                    logger.error("An exception occurred while getting the Quartz scheduler: {}",
                                            e1.getMessage());
                                }

                                JobDataMap map = new JobDataMap();
                                map.put("Channel", theElement.channel);
                                map.put("Binding", this);

                                JobDetail job = null;
                                Trigger trigger = null;

                                job = newJob(ReconnectJob.class)
                                        .withIdentity(
                                                Integer.toHexString(hashCode()) + "-Reconnect-"
                                                        + Long.toString(System.currentTimeMillis()),
                                                this.toString())
                                        .usingJobData(map).build();

                                trigger = newTrigger()
                                        .withIdentity(
                                                Integer.toHexString(hashCode()) + "-Reconnect-"
                                                        + Long.toString(System.currentTimeMillis()),
                                                this.toString())
                                        .startAt(futureDate(reconnectInterval, IntervalUnit.SECOND)).build();

                                try {
                                    if (job != null && trigger != null && selKey != listenerKey) {
                                        if (!theElement.channel.isReconnecting) {
                                            channels.setAllReconnecting(theElement.channel.channel, true);
                                            scheduler.scheduleJob(job, trigger);
                                        }
                                    }
                                } catch (SchedulerException e) {
                                    logger.error(
                                            "An exception occurred while scheduling a job with the Quartz Scheduler {}",
                                            e.getMessage());
                                }
                            }
                        } else {
                            if (theElement != null) {
                                writeQueue.remove(theElement);
                            }

                        }
                    }
                }
            }
        }
    }
}

From source file:org.gcaldaemon.core.ldap.LDAPListener.java

public final void run() {
    log.info("LDAP server started successfully.");

    // Create variables
    SelectionKey key, newKey;
    SocketChannel channel;/* w w  w. j av  a  2s .c o  m*/
    Socket socket = null;
    Iterator keys;
    int n;

    // Server loop
    for (;;) {
        try {

            // Select sockets
            try {
                socket = null;
                n = selector.select();
            } catch (NullPointerException closedError) {

                // Ignore Selector bug - client socket closed
                if (log.isDebugEnabled()) {
                    log.debug("Socket closed.", closedError);
                }
                continue;
            } catch (ClosedSelectorException interrupt) {
                break;
            } catch (Exception selectError) {

                // Unknown exception - stop server
                log.warn("Unable to select sockets!", selectError);
                break;
            }

            if (n != 0) {

                // Get an iterator over the set of selected keys
                keys = selector.selectedKeys().iterator();
                if (keys == null) {
                    continue;
                }

                // Look at each key in the selected set
                while (keys.hasNext()) {
                    key = (SelectionKey) keys.next();
                    keys.remove();

                    // Nothing to do
                    if (key == null) {
                        continue;
                    }

                    // Check key status
                    if (key.isValid()) {

                        // Accept new incoming connection
                        if (key.isAcceptable()) {
                            channel = serverChannel.accept();
                            if (channel != null) {

                                // Register new socket connection
                                socket = channel.socket();
                                channel.configureBlocking(false);
                                newKey = channel.register(selector, SelectionKey.OP_READ);
                                processAccept(newKey);
                            }
                        } else {
                            if (key.isReadable()) {

                                // Read from socket connection
                                socket = ((SocketChannel) key.channel()).socket();
                                processRead(key);
                            } else {

                                // Write to socket connection
                                if (key.isWritable()) {
                                    socket = ((SocketChannel) key.channel()).socket();
                                    processWrite(key);
                                }
                            }
                        }
                    }
                }
            }
        } catch (InterruptedException interrupt) {
            closeSocket(socket);
            break;
        } catch (IOException socketClosed) {
            closeSocket(socket);
            continue;
        } catch (Exception processingException) {
            closeSocket(socket);
            log.warn(processingException.getMessage(), processingException);
        }
    }
    log.info("LDAP server stopped.");
}