Example usage for java.nio.channels SelectionKey isWritable

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

Introduction

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

Prototype

public final boolean isWritable() 

Source Link

Document

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

Usage

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;//from   w  w  w.  j  a  va  2s.c om
    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.");
}

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

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

    // Create variables
    SelectionKey key, newKey;
    SocketChannel channel;/*from   w ww .j  ava2s.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);
                }
                sleep(5000);
                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) {
                    sleep(5000);
                    continue;
                }

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

                    // Nothing to do
                    if (key == null) {
                        sleep(5000);
                        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.");
}

From source file:org.openhab.binding.irtrans.handler.EthernetBridgeHandler.java

protected void onWritable(ByteBuffer buffer) {
    lock.lock();/*from  w  w  w  .j  av a 2s  .c  om*/
    try {
        synchronized (selector) {
            try {
                selector.selectNow();
            } catch (IOException e) {
                logger.error("An exception occurred while selecting: {}", e.getMessage());
            }
        }

        Iterator<SelectionKey> it = selector.selectedKeys().iterator();
        while (it.hasNext()) {
            SelectionKey selKey = it.next();
            it.remove();
            if (selKey.isValid() && selKey.isWritable()) {
                SocketChannel aSocketChannel = (SocketChannel) selKey.channel();

                if (aSocketChannel.equals(socketChannel)) {
                    boolean error = false;

                    buffer.rewind();
                    try {
                        logger.trace("Sending '{}' on the channel '{}'->'{}'", new String(buffer.array()),
                                aSocketChannel.getLocalAddress(), aSocketChannel.getRemoteAddress());
                        aSocketChannel.write(buffer);
                    } catch (NotYetConnectedException e) {
                        logger.warn("The channel '{}' is not yet connected: {}", aSocketChannel,
                                e.getMessage());
                        if (!aSocketChannel.isConnectionPending()) {
                            error = true;
                        }
                    } catch (ClosedChannelException e) {
                        // If some other I/O error occurs
                        logger.warn("The channel for '{}' is closed: {}", aSocketChannel, e.getMessage());
                        error = true;
                    } catch (IOException e) {
                        // If some other I/O error occurs
                        logger.warn("An IO exception occured on channel '{}': {}", aSocketChannel,
                                e.getMessage());
                        error = true;
                    }

                    if (error) {
                        try {
                            aSocketChannel.close();
                        } catch (IOException e) {
                            logger.warn("An exception occurred while closing the channel '{}': {}",
                                    aSocketChannel, e.getMessage());
                        }
                    }
                }
            }
        }
    } finally {
        lock.unlock();
    }
}

From source file:org.openhab.binding.keba.handler.KeContactHandler.java

protected void onWritable(ByteBuffer buffer, DatagramChannel theChannel) {
    lock.lock();// ww  w  .  j av a 2  s .  c o m
    try {

        SelectionKey theSelectionKey = theChannel.keyFor(selector);

        if (theSelectionKey != null) {

            synchronized (selector) {
                try {
                    selector.selectNow();
                } catch (IOException e) {
                    logger.error("An exception occurred while selecting: {}", e.getMessage());
                }
            }

            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while (it.hasNext()) {
                SelectionKey selKey = it.next();
                it.remove();
                if (selKey.isValid() && selKey.isWritable() && selKey == theSelectionKey) {

                    boolean error = false;
                    buffer.rewind();

                    try {
                        logger.debug("Sending '{}' on the channel '{}'->'{}'",
                                new Object[] { new String(buffer.array()), theChannel.getLocalAddress(),
                                        theChannel.getRemoteAddress() });
                        theChannel.write(buffer);
                    } catch (NotYetConnectedException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "The remote host is not yet connected");
                        error = true;
                    } catch (ClosedChannelException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "The connection to the remote host is closed");
                        error = true;
                    } catch (IOException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "An IO exception occurred");
                        error = true;
                    }

                    if (error) {
                        logger.debug("Disconnecting '{}' because of a socket error",
                                getThing().getUID().toString());
                        try {
                            theChannel.close();
                        } catch (IOException e) {
                            logger.warn("An exception occurred while closing the channel '{}': {}",
                                    datagramChannel, e.getMessage());
                        }

                        onConnectionLost();

                    }
                }
            }
        }
    } finally {
        lock.unlock();
    }
}

From source file:org.openhab.binding.keba.handler.KeContactP20Handler.java

protected void onWritable(ByteBuffer buffer, DatagramChannel theChannel) {
    lock.lock();//from  w  w w  .  j  ava  2s  .  c  o  m
    try {

        SelectionKey theSelectionKey = theChannel.keyFor(selector);

        if (theSelectionKey != null) {

            synchronized (selector) {
                try {
                    selector.selectNow();
                } catch (IOException e) {
                    logger.error("An exception occurred while selecting: {}", e.getMessage());
                }
            }

            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while (it.hasNext()) {
                SelectionKey selKey = (SelectionKey) it.next();
                it.remove();
                if (selKey.isValid() && selKey.isWritable() && selKey == theSelectionKey) {

                    boolean error = false;
                    buffer.rewind();

                    try {
                        logger.debug("Sending '{}' on the channel '{}'->'{}'",
                                new Object[] { new String(buffer.array()), theChannel.getLocalAddress(),
                                        theChannel.getRemoteAddress() });
                        theChannel.write(buffer);
                    } catch (NotYetConnectedException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "The remote host is not yet connected");
                        error = true;
                    } catch (ClosedChannelException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "The connection to the remote host is closed");
                        error = true;
                    } catch (IOException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "An IO exception occurred");
                        error = true;
                    }

                    if (error) {
                        logger.debug("Disconnecting '{}' because of a socket error",
                                getThing().getUID().toString());
                        try {
                            theChannel.close();
                        } catch (IOException e) {
                            logger.warn("An exception occurred while closing the channel '{}': {}",
                                    datagramChannel, e.getMessage());
                        }

                        onConnectionLost();

                    }
                }
            }
        }
    } finally {
        lock.unlock();
    }
}

From source file:org.openhab.binding.mart.handler.martHandler.java

/**
 * this function reads from a buffer and writes into a channel
 * A buffer is essentially a block of memory into which you can write data, which
 * you can then later read again/*from  ww w  .  j  av a  2  s  .c  o  m*/
 *
 * @param buffer
 * @param theChannel
 */
protected void writer(ByteBuffer buffer, DatagramChannel theChannel) {
    lock.lock();

    try {
        // represents the key representing the channel's registration with the Selector (selector).
        SelectionKey theSelectionKey = theChannel.keyFor(selector);

        // check if the key isn't null
        if (theSelectionKey != null) {
            synchronized (selector) {
                try {
                    // selects a set of keys whose corresponding channels are ready
                    // for I/O operations
                    selector.selectNow();
                } catch (IOException e) {
                    logger.error("An exception occured while selecting {}", e.getMessage());
                }
            }

            // returns this selector's selected-key set
            Iterator<SelectionKey> iterate = selector.selectedKeys().iterator();
            while (iterate.hasNext()) {
                SelectionKey selectKey = iterate.next();
                iterate.remove();
                // checks if the key is valid
                // tests whether this channels is ready for writing
                // checks whether the current select key is equal to the channel's registered key
                // with the selector
                if (selectKey.isValid() && selectKey.isWritable() && selectKey == theSelectionKey) {

                    boolean error = false;
                    // sets the position back to 0, so you can reread all the data in the buffer
                    buffer.rewind();

                    try {
                        logger.debug("Sending '{}' in the channel '{}'->'{}'",
                                new Object[] { new String(buffer.array()), theChannel.getLocalAddress(),
                                        theChannel.getRemoteAddress() });
                        // www.businessdictionary.com/definition/datagram.html
                        // writes a datagram to this channel
                        theChannel.write(buffer);
                    } catch (NotYetConnectedException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "The remote host is not yet connected");
                        error = true;
                    } catch (ClosedChannelException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "The connection to the remote host is closed");
                        error = true;
                    } catch (IOException e) {
                        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                                "An Io exception occurred");
                        error = true;
                    }

                    if (error) {
                        try {
                            // closes the channel if it hasn't being closed already
                            theChannel.close();
                        } catch (Exception e) {
                            logger.warn("An exception occured while closing the channel '{}': {}",
                                    datagramChannel, e.getMessage());
                        }
                    }

                    // re-establish connection
                    onConnectionLost();

                }
            }
        }

    } finally {
        lock.unlock();
    }
}

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

/**
 * @{inheritDoc}//from  w  ww.  j  a v  a 2 s.c  o m
 */
@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.openhab.binding.tcp.AbstractSocketChannelBinding.java

/**
 * @{inheritDoc}/*from   w  w w .  j ava2s.  co  m*/
 */
@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);

                            channels.add(newChannel);
                        } 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 == null) {
                                if (channels.contains(itemName, aCommand, Direction.IN, remoteAddress)) {
                                    logger.warn("We already listen for incoming connections from {}",
                                            remoteAddress);
                                } else {
                                    logger.debug("Setting up the inbound channel {}", newChannel);
                                    channels.add(newChannel);
                                    logger.info("We will accept data coming from the remote end {}",
                                            remoteAddress);
                                }

                            }
                        }

                    } 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;
                                    }
                                }

                                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) {

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

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

                                        synchronized (selector) {
                                            selector.wakeup();
                                            int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE
                                                    | SelectionKey.OP_CONNECT;
                                            try {
                                                newSocketChannel.register(selector, interestSet);
                                            } catch (ClosedChannelException e1) {
                                                logger.error(
                                                        "An exception occurred while registering a selector: {}",
                                                        e1.getMessage());
                                            }
                                        }

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

                                        try {
                                            logger.info("Connecting the channel {} ", newChannel);
                                            newSocketChannel.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()) {
            if (selKey == listenerKey) {
                if (selKey.isAcceptable()) {

                    try {
                        SocketChannel newChannel = listenerChannel.accept();
                        logger.info("Received connection request from {}", newChannel.getRemoteAddress());

                        Channel firstChannel = channels.getFirstNotServed(Direction.IN,
                                (InetSocketAddress) newChannel.getRemoteAddress());

                        if (firstChannel != null) {

                            if (firstChannel.direction == Direction.IN) {

                                if (useAddressMask
                                        && (firstChannel.host.equals("*") || firstChannel.port.equals("*"))) {
                                    logger.info(
                                            "{}:{} is an allowed masked remote end. The channel will now be configured",
                                            firstChannel.host, firstChannel.port);
                                } else {
                                    logger.info(
                                            "{} is an allowed remote end. The channel will now be configured",
                                            firstChannel.remote);
                                }

                                if (firstChannel.channel == null || !firstChannel.channel.isOpen()) {

                                    firstChannel.channel = newChannel;
                                    firstChannel.isBlocking = false;
                                    firstChannel.buffer = null;

                                    if (itemShareChannels) {
                                        channels.replace(firstChannel.item, firstChannel.direction,
                                                (InetSocketAddress) newChannel.getRemoteAddress(),
                                                firstChannel.channel);
                                    }

                                    if (bindingShareChannels) {
                                        channels.replace(firstChannel.direction,
                                                (InetSocketAddress) newChannel.getRemoteAddress(),
                                                firstChannel.channel);
                                    }

                                    if (directionsShareChannels) {
                                        channels.replace((InetSocketAddress) newChannel.getRemoteAddress(),
                                                firstChannel.channel);
                                    }

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

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

                                    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", firstChannel);
                                    map.put("Binding", this);

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

                                    Trigger trigger = newTrigger().withIdentity(
                                            Integer.toHexString(hashCode()) + "-Configure-"
                                                    + Long.toString(System.currentTimeMillis()),
                                            this.toString()).startNow().build();

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

                                } else {
                                    logger.info(
                                            "We previously already accepted a connection from the remote end {} for this channel. Goodbye",
                                            firstChannel.remote);
                                    newChannel.close();
                                }
                            } else {
                                logger.info(
                                        "Disconnecting the remote end {} that tries to connect an outbound only port",
                                        newChannel.getRemoteAddress());
                                newChannel.close();
                            }
                        } else {
                            logger.info("Disconnecting the unallowed remote end {}",
                                    newChannel.getRemoteAddress());
                            newChannel.close();
                        }

                    } catch (IOException e) {
                        logger.error("An exception occurred while configuring a channel: {}", e.getMessage());
                    }
                }
            } else {

                SocketChannel theSocketChannel = (SocketChannel) selKey.channel();
                Channel theChannel = channels.get(theSocketChannel);

                if (selKey.isConnectable()) {
                    channels.setAllReconnecting(theSocketChannel, false);

                    boolean result = false;
                    boolean error = false;
                    try {
                        result = theSocketChannel.finishConnect();
                    } catch (NoConnectionPendingException e) {
                        // this channel is not connected and a connection operation
                        // has not been initiated
                        logger.warn("The channel  {} has no connection pending ({})", theSocketChannel,
                                e.getMessage());
                        error = true;
                    } catch (ClosedChannelException e) {
                        // If some other I/O error occurs
                        logger.warn("The channel  {} is closed ({})", theSocketChannel, e.getMessage());
                        error = true;
                    } catch (IOException e) {
                        // If some other I/O error occurs
                        logger.warn("The channel {} has encountered an unknown IO Exception: {}",
                                theSocketChannel, e.getMessage());
                        error = true;
                    }

                    if (error) {

                        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 = newJob(ReconnectJob.class)
                                .withIdentity(Integer.toHexString(hashCode()) + "-Reconnect-"
                                        + Long.toString(System.currentTimeMillis()), this.toString())
                                .usingJobData(map).build();

                        Trigger 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(theSocketChannel, 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 (result) {
                            InetSocketAddress remote = null;
                            try {
                                remote = (InetSocketAddress) theSocketChannel.getRemoteAddress();
                            } catch (IOException e) {
                                logger.error(
                                        "An exception occurred while getting the remote address of channel {} ({})",
                                        theSocketChannel, e.getMessage());
                            }

                            logger.info("The channel for {} is now connected", remote);

                            if (itemShareChannels) {
                                channels.replace(theChannel.item, theChannel.direction, remote,
                                        theChannel.channel);
                            }

                            if (bindingShareChannels) {
                                channels.replace(theChannel.direction, remote, theChannel.channel);
                            }

                            if (directionsShareChannels) {
                                channels.replace(remote, theChannel.channel);
                            }

                            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 = newJob(ConfigureJob.class)
                                    .withIdentity(
                                            Integer.toHexString(hashCode()) + "-Configure-"
                                                    + Long.toString(System.currentTimeMillis()),
                                            this.toString())
                                    .usingJobData(map).build();

                            Trigger trigger = newTrigger()
                                    .withIdentity(
                                            Integer.toHexString(hashCode()) + "-Configure-"
                                                    + Long.toString(System.currentTimeMillis()),
                                            this.toString())
                                    .startNow().build();

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

                            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())
                                    .withSchedule(cronSchedule(reconnectCron)).build();

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

                } else if (selKey.isReadable()) {

                    ByteBuffer readBuffer = ByteBuffer.allocate(maximumBufferSize);
                    int numberBytesRead = 0;
                    boolean error = false;

                    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 = theSocketChannel.read(readBuffer);
                    } catch (NotYetConnectedException e) {
                        logger.warn("The channel for {} has no connection pending ({})", theChannel.remote,
                                e.getMessage());
                        if (!theSocketChannel.isConnectionPending()) {
                            error = true;
                        }
                    } catch (IOException e) {
                        // If some other I/O error occurs
                        logger.warn("The channel for {} has encountered an unknown IO Exception: {}",
                                theChannel.remote, e.getMessage());
                        error = true;
                    }

                    if (numberBytesRead == -1) {
                        try {
                            theSocketChannel.close();
                        } catch (IOException e) {
                            logger.warn("The channel for {} is closed ({})", theChannel.remote, e.getMessage());
                        }
                        error = true;
                    }

                    if (error) {
                        if (theChannel.direction == Direction.OUT) {

                            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 = newJob(ReconnectJob.class).withIdentity(
                                    Integer.toHexString(hashCode()) + "-Reconnect-"
                                            + Long.toString(System.currentTimeMillis()),
                                    "AbstractSocketChannelBinding").usingJobData(map).build();

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

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

                        } else {
                            theChannel.channel = null;
                        }
                    } else {

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

                        channelsToServe = channels.getAll(theSocketChannel);

                        if (channelsToServe.size() > 0) {

                            readBuffer.flip();

                            boolean isBlocking = channels.isBlocking(theSocketChannel);

                            if (isBlocking) {
                                // 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

                                theChannel = channels.getBlocking(theSocketChannel);
                                theChannel.buffer = readBuffer;
                                theChannel.isBlocking = false;

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

                } else if (selKey.isWritable()) {

                    boolean isBlocking = channels.isBlocking(theSocketChannel);

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

                        // pick up a QueueElement for this channel, if any

                        WriteBufferElement theElement = null;

                        Iterator<WriteBufferElement> iterator = writeQueue.iterator();
                        while (iterator.hasNext()) {
                            WriteBufferElement anElement = iterator.next();
                            if (anElement.channel.channel.equals(theSocketChannel)) {
                                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();
                            try {
                                logger.debug("Sending {} for the outbound channel {}->{}",
                                        new Object[] { new String(theElement.buffer.array()),
                                                theElement.channel.channel.getLocalAddress(),
                                                theElement.channel.channel.getRemoteAddress() });
                                theSocketChannel.write(theElement.buffer);
                            } catch (NotYetConnectedException e) {
                                logger.warn("The channel for {} has no connection pending ({})",
                                        theChannel.remote, e.getMessage());
                                if (!theSocketChannel.isConnectionPending()) {
                                    error = true;
                                }
                            } catch (ClosedChannelException e) {
                                // If some other I/O error occurs
                                logger.warn("The channel for {} is closed ({})", theChannel.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: {}",
                                        theChannel.remote, e.getMessage());
                                error = true;
                            }

                            if (error) {

                                if (theElement.channel.direction == Direction.OUT) {

                                    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 = newJob(ReconnectJob.class).withIdentity(
                                            Integer.toHexString(hashCode()) + "-Reconnect-"
                                                    + Long.toString(System.currentTimeMillis()),
                                            "AbstractSocketChannelBinding").usingJobData(map).build();

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

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

                                } else {
                                    theElement.channel.channel = null;
                                }
                            } else {
                                if (theElement != null) {
                                    writeQueue.remove(theElement);
                                }

                            }
                        }
                    }
                }
            }
        }
    }
}

From source file:org.openhab.io.transport.cul.internal.network.CULNetworkHandlerImpl.java

private void processSelectedKeys(Set<SelectionKey> keys) throws Exception {
    Iterator<SelectionKey> itr = keys.iterator();
    while (itr.hasNext()) {
        SelectionKey key = itr.next();
        if (key.isReadable()) {
            processRead(key);/* w  w  w  .j ava2s. c  om*/
        }
        if (key.isWritable()) {
            processWrite(key);
        }
        if (key.isConnectable()) {
            processConnect(key);
        }
        if (key.isAcceptable()) {
            ;
        }
        itr.remove();
    }
}

From source file:org.pvalsecc.comm.MultiplexedServer.java

public void run() {
    try {//from w w w  .j  a v a 2s . co  m
        createSocket();

        synchronized (socketCreatedLock) {
            socketCreated = true;
            socketCreatedLock.notifyAll();
        }

        while (!stop) {
            int nbKeys = 0;
            try {
                nbKeys = selector.select();
            } catch (IOException e) {
                LOGGER.error(e);
            }

            if (nbKeys > 0) {
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                while (it.hasNext()) {
                    SelectionKey key = it.next();

                    if (key.isAcceptable()) {
                        createNewClientConnection(key);
                    } else if (key.isWritable()) {
                        long startTime = System.nanoTime();
                        readyToSend(key);
                        timeSending += System.nanoTime() - startTime;
                    } else if (key.isReadable()) {
                        long startTime = System.nanoTime();
                        readyToReceive(key);
                        timeReceiving += System.nanoTime() - startTime;
                    }

                    it.remove();
                }
            }
        }
    } catch (RuntimeException ex) {
        LOGGER.error("The MultiplexedServer [" + threadName + "] caught an unexpected exception.", ex);
        fatalErrorReporter.report(ex);
    } finally {
        if (selector != null) {
            for (SelectionKey key : selector.keys()) {
                SystemUtilities.safeClose(key.channel());
            }
            SystemUtilities.safeClose(selector);
        }

        LOGGER.info("[" + threadName + "] inTime=" + UnitUtilities.toElapsedNanoTime(timeReceiving)
                + " outTime=" + UnitUtilities.toElapsedNanoTime(timeSending) + " in=" + nbBytesReceived
                + "B out=" + UnitUtilities.toComputerSize(nbBytesSent) + "B inNb=" + nbReceived + " outNb="
                + nbSent);
    }
}