List of usage examples for java.nio.channels SelectionKey isValid
public abstract boolean isValid();
From source file:org.openhab.binding.mart.handler.martHandler.java
/** * Reads a buffer from the channel and returns it * A buffer is essentially a block of memory into which you can write data, which * you can then later read again/*from www. ja va2s .co m*/ * * @param theChannel * @param bufferSize * @param permittedClientAddress * @return */ protected ByteBuffer Reader(DatagramChannel theChannel, int bufferSize, InetAddress permittedClientAddress) { // The lock() method locks the Lock instance so that all threads calling lock() are blocked until unlock() is // executed. lock.lock(); try { // retrieves the channel's key representing its registration with the selector SelectionKey theSelectionKey = theChannel.keyFor(selector); if (theSelectionKey != null) { synchronized (selector) { try { // it 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()); } catch (ClosedSelectorException e) { logger.error("An exception occured while selecting: {}", e.getMessage()); } } // to iterate over the this selector's selected key set Iterator<SelectionKey> iterate = selector.selectedKeys().iterator(); // if iterate has more elements while (iterate.hasNext()) { // represents the key representing the channel's registration with the Selector (selector). SelectionKey selectKey = iterate.next(); iterate.remove(); if (selectKey.isValid() && selectKey.isReadable() && selectKey == theSelectionKey) { // allocate a new byte buffer with 1024 bytes capacity ByteBuffer readBuffer = ByteBuffer.allocate(bufferSize); int numOfBytesRead = 0; boolean error = false; // if the current select key is the key representing the listener's channel registration // with the selector, then read the byte buffer or data from the channel if (selectKey == listenerKey) { try { // receive a datagram via this channel // the channel writes data into the the readBuffer InetSocketAddress clientAddress = (InetSocketAddress) theChannel .receive(readBuffer); // if the returned address given by the receive() is == permitted address if (clientAddress.getAddress().equals(permittedClientAddress)) { logger.debug("Received {} on the listener port from {}", new String(readBuffer.array()), clientAddress); // returns the buffer's position to help as check whether the buffer is // full or not numOfBytesRead = readBuffer.position(); } else { logger.warn( "Received data from '{}' which is not the permitted remote address '{}'", clientAddress, permittedClientAddress); // since it is not a permitted remote address return nothing return null; } } catch (Exception e) { logger.error( "An exception occurred while receiving data on the listener port: '{}'", e.getMessage()); error = true; } // if the selectKey != listenerKey } else { try { // reads a datagram from this channel though the selectKey != listenerKey // reads a data from this channel into the readBuffer or // the channel writes data into the the buffer numOfBytesRead = theChannel.read(readBuffer); } catch (NotYetConnectedException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "The MART adapter is not yet connected"); error = true; } catch (PortUnreachableException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "This is probably not a MART adapter"); error = true; } catch (IOException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "An IO exception occurred"); error = true; } } // if numOfBytesRead == -1 then the channel has reached end of stream if (numOfBytesRead == -1) { error = true; } // if error == true , close the channel and re-establish connection if (error) { logger.debug("Disconnecting '{}' because of a socket error", getThing().getUID().toString()); try { // close the channel theChannel.close(); } catch (IOException e) { logger.error("An exception occurred while closing the channel '{}': {}", datagramChannel, e.getMessage()); } // re-establish connection onConnectionLost(); // if error == false, } else { // switch the buffer from writing mode into reading mode and return it readBuffer.flip(); return readBuffer; } } } } return null; } 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 a v a 2 s .co 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}//www.j av a 2s . 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); } 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 . ja v a2s .com*/ */ @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.quickserver.net.server.QuickServer.java
/** * Starts server in non-blocking mode./* w w w .j a va 2 s . c o m*/ * @since 1.4.5 */ private void runNonBlocking(TheClient theClient) throws Exception { int selectCount = 0; Iterator iterator = null; SelectionKey key = null; ServerSocketChannel serverChannel = null; SocketChannel socketChannel = null; Socket client = null; ClientHandler _chPolled = null; boolean stopServerProcessed = false; int linger = getBasicConfig().getAdvancedSettings().getSocketLinger(); registerChannelRequestMap = new HashMap(); int socketTrafficClass = 0; if (getBasicConfig().getAdvancedSettings().getClientSocketTrafficClass() != null) { socketTrafficClass = Integer .parseInt(getBasicConfig().getAdvancedSettings().getClientSocketTrafficClass()); } while (true) { selectCount = selector.select(500); //selectCount = selector.select();//for testing //check for any pending registerChannel req. synchronized (registerChannelRequestMap) { if (registerChannelRequestMap.size() > 0) { RegisterChannelRequest req = null; Object hashkey = null; iterator = registerChannelRequestMap.keySet().iterator(); while (iterator.hasNext()) { hashkey = iterator.next(); req = (RegisterChannelRequest) registerChannelRequestMap.get(hashkey); req.register(getSelector()); } iterator = null; registerChannelRequestMap.clear(); } //if } //sync if (stopServer == true && stopServerProcessed == false) { logger.warning("Closing " + getName()); serverSocketChannel.close(); stopServerProcessed = true; server = null; serverSocketChannel = null; setServiceState(Service.STOPPED); logger.warning("Closed " + getName()); processServerHooks(ServerHook.POST_SHUTDOWN); } if (stopServer == false && stopServerProcessed == true) { logger.finest("Server must have re-started.. will break"); break; } if (selectCount == 0 && stopServerProcessed == true) { java.util.Set keyset = selector.keys(); if (keyset.isEmpty() == true && getClientCount() <= 0) { break; } else { continue; } } else if (selectCount == 0) { continue; } iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { key = (SelectionKey) iterator.next(); if (key.isValid() == false) { iterator.remove(); continue; } if (key.isAcceptable() && stopServer == false) { logger.finest("Key is Acceptable"); serverChannel = (ServerSocketChannel) key.channel(); socketChannel = serverChannel.accept(); if (socketChannel == null) { iterator.remove(); continue; } client = socketChannel.socket(); if (linger < 0) { client.setSoLinger(false, 0); } else { client.setSoLinger(true, linger); } client.setTcpNoDelay(getBasicConfig().getAdvancedSettings().getClientSocketTcpNoDelay()); if (getBasicConfig().getAdvancedSettings().getClientSocketTrafficClass() != null) { client.setTrafficClass(socketTrafficClass);//low delay=10 } //logger.fine("ReceiveBufferSize: "+client.getReceiveBufferSize()); if (getBasicConfig().getAdvancedSettings().getClientSocketSendBufferSize() != 0) { client.setSendBufferSize( getBasicConfig().getAdvancedSettings().getClientSocketSendBufferSize()); //logger.fine("SendBufferSize: "+client.getSendBufferSize()); } if (checkAccessConstraint(client) == false) { iterator.remove(); continue; } socketChannel.configureBlocking(false); theClient.setTrusted(getSkipValidation()); theClient.setSocket(socketChannel.socket()); theClient.setSocketChannel(socketChannel); if (clientDataClass != null) { if (getClientDataPool() == null) { clientData = (ClientData) clientDataClass.newInstance(); } else { //borrow a object from pool clientData = (ClientData) getClientDataPool().borrowObject(); } theClient.setClientData(clientData); } //Check if max connection has reached if (getSkipValidation() != true && maxConnection != -1 && getClientHandlerPool().getNumActive() >= maxConnection) { theClient.setClientEvent(ClientEvent.MAX_CON); } else { theClient.setClientEvent(ClientEvent.ACCEPT); } try { _chPolled = (ClientHandler) getClientHandlerPool().borrowObject(); logger.finest("Asking " + _chPolled.getName() + " to handle."); _chPolled.handleClient(theClient); } catch (java.util.NoSuchElementException nsee) { logger.warning("Could not borrow ClientHandler Object from pool. Error: " + nsee); logger.warning("Closing SocketChannel [" + serverChannel.socket() + "] since no ClientHandler available."); socketChannel.close(); } if (_chPolled != null) { try { getClientPool().addClient(_chPolled, true); } catch (java.util.NoSuchElementException nsee) { logger.warning("Could not borrow Thread from pool. Error: " + nsee); //logger.warning("Closing SocketChannel ["+serverChannel.socket()+"] since no Thread available."); //socketChannel.close(); //returnClientHandlerToPool(_chPolled); } _chPolled = null; } socketChannel = null; client = null; setSkipValidation(false);//reset it back } else if (key.isValid() && key.isReadable()) { boolean addedEvent = false; ClientHandler _ch = null; try { _ch = (ClientHandler) key.attachment(); logger.finest("Key is Readable, removing OP_READ from interestOps for " + _ch.getName()); key.interestOps(key.interestOps() & (~SelectionKey.OP_READ)); _ch.addEvent(ClientEvent.READ); addedEvent = true; //_ch.setSelectionKey(key); getClientPool().addClient(_ch); } catch (CancelledKeyException cke) { logger.fine("Ignored Error - Key was Cancelled: " + cke); } catch (java.util.NoSuchElementException nsee) { logger.finest("NoSuchElementException: " + nsee); if (addedEvent) _ch.removeEvent(ClientEvent.READ); continue;//no need to remove the key } _ch = null; } else if (key.isValid() && key.isWritable()) { if (getClientPool().shouldNioWriteHappen() == false) { continue; //no need to remove the key } boolean addedEvent = false; ClientHandler _ch = null; try { _ch = (ClientHandler) key.attachment(); logger.finest("Key is Writable, removing OP_WRITE from interestOps for " + _ch.getName()); //remove OP_WRITE from interest set key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE)); _ch.addEvent(ClientEvent.WRITE); addedEvent = true; //_ch.setSelectionKey(key); getClientPool().addClient(_ch); } catch (CancelledKeyException cke) { logger.fine("Ignored Error - Key was Cancelled: " + cke); } catch (java.util.NoSuchElementException nsee) { logger.finest("NoSuchElementException: " + nsee); if (addedEvent) _ch.removeEvent(ClientEvent.WRITE); continue;//no need to remove the key } _ch = null; } else if (stopServer == true && key.isAcceptable()) { //we will not accept this key setSkipValidation(false);//reset it back } else { logger.warning("Unknown key got in SelectionKey: " + key); } iterator.remove(); //Remove key Thread.yield(); } //end of iterator iterator = null; } //end of loop }
From source file:org.sipfoundry.sipxbridge.symmitron.DataShuffler.java
/** * Sit in a loop running the following algorthim till exit: * /*www . j av a2 s.co m*/ * <pre> * Let Si be a Sym belonging to Bridge B where an inbound packet P is received * Increment received packet count for B. * Record time for the received packet. * Record inboundAddress from where the packet was received * send(B,chan,inboundAddress) * * </pre> * */ public void run() { // Wait for an event one of the registered channels logger.debug("Starting Shuffler"); while (true) { Bridge bridge = null; try { if (initializeSelectors.get()) { initializeSelector(); } selector.select(); while (!workQueue.isEmpty()) { logger.debug("Got a work item"); WorkItem workItem = (WorkItem) workQueue.remove(0); workItem.doWork(); } // Iterate over the set of keys for which events are // available Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = (SelectionKey) selectedKeys.next(); // The key must be removed or you can get one way audio ( i.e. will read a // null byte ). // (see issue 2075 ). selectedKeys.remove(); if (!key.isValid()) { if (logger.isDebugEnabled()) { logger.debug("Discarding packet:Key not valid"); } continue; } if (key.isReadable()) { readBuffer.clear(); DatagramChannel datagramChannel = (DatagramChannel) key.channel(); if (!datagramChannel.isOpen()) { if (logger.isDebugEnabled()) { logger.debug("DataShuffler: Datagram channel is closed -- discarding packet."); } continue; } bridge = ConcurrentSet.getBridge(datagramChannel); if (bridge == null) { if (logger.isDebugEnabled()) { logger.debug("DataShuffler: Discarding packet: Could not find bridge"); } continue; } Sym packetReceivedSym = bridge.getReceiverSym(datagramChannel); /* * Note the original hold value and put the transmitter on which this packet was received on hold. */ if (packetReceivedSym == null || packetReceivedSym.getTransmitter() == null) { if (logger.isDebugEnabled()) { logger.debug( "DataShuffler: Could not find sym for inbound channel -- discarding packet"); } continue; } boolean holdValue = packetReceivedSym.getTransmitter().isOnHold(); packetReceivedSym.getTransmitter().setOnHold(true); InetSocketAddress remoteAddress = (InetSocketAddress) datagramChannel.receive(readBuffer); bridge.pakcetsReceived++; if (bridge.getState() != BridgeState.RUNNING) { if (logger.isDebugEnabled()) { logger.debug( "DataShuffler: Discarding packet: Bridge state is " + bridge.getState()); } packetReceivedSym.getTransmitter().setOnHold(holdValue); continue; } if (logger.isTraceEnabled()) { logger.trace("got something on " + datagramChannel.socket().getLocalPort()); } long stamp = getPacketCounter(); send(bridge, datagramChannel, remoteAddress, stamp, false); /* * Reset the old value. */ packetReceivedSym.getTransmitter().setOnHold(holdValue); } } } catch (Exception ex) { logger.error("Unexpected exception occured", ex); if (bridge != null && bridge.sessions != null) { for (Sym rtpSession : bridge.sessions) { rtpSession.close(); } } if (bridge != null) bridge.setState(BridgeState.TERMINATED); continue; } } }
From source file:org.sipfoundry.sipxbridge.symmitron.DataShuffler.java
/** * //from ww w. java2 s.com * Implements the following search algorithm to retrieve a datagram channel that is associated * with the far end: * * <pre> * getSelfRoutedDatagramChannel(farEnd) * For each selectable key do: * let ipAddress be the local ip address * let p be the local port * let d be the datagramChannel associated with the key * If farEnd.ipAddress == ipAddress && port == localPort return d * return null * </pre> * * @param farEnd * @return */ public static DatagramChannel getSelfRoutedDatagramChannel(InetSocketAddress farEnd) { // Iterate over the set of keys for which events are // available InetAddress ipAddress = farEnd.getAddress(); int port = farEnd.getPort(); for (Iterator<SelectionKey> selectedKeys = selector.keys().iterator(); selectedKeys.hasNext();) { SelectionKey key = selectedKeys.next(); if (!key.isValid()) { continue; } DatagramChannel datagramChannel = (DatagramChannel) key.channel(); if (datagramChannel.socket().getLocalAddress().equals(ipAddress) && datagramChannel.socket().getLocalPort() == port) { return datagramChannel; } } return null; }
From source file:org.sipfoundry.sipxrelay.DataShuffler.java
/** * Sit in a loop running the following algorthim till exit: * //from w w w .j a v a 2 s . c om * <pre> * Let Si be a Sym belonging to Bridge B where an inbound packet P is received * Increment received packet count for B. * Record time for the received packet. * Record inboundAddress from where the packet was received * send(B,chan,inboundAddress) * * </pre> * */ public void run() { // Wait for an event one of the registered channels logger.debug("Starting Shuffler"); while (true) { Bridge bridge = null; try { if (initializeSelectors.get()) { initializeSelector(); } selector.select(); checkWorkQueue(); // Iterate over the set of keys for which events are // available Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = (SelectionKey) selectedKeys.next(); // The key must be removed or you can get one way audio ( i.e. will read a // null byte ). // (see issue 2075 ). selectedKeys.remove(); if (!key.isValid()) { if (logger.isDebugEnabled()) { logger.debug("Discarding packet:Key not valid"); } continue; } if (key.isReadable()) { readBuffer.clear(); DatagramChannel datagramChannel = (DatagramChannel) key.channel(); if (!datagramChannel.isOpen()) { if (logger.isDebugEnabled()) { logger.debug("DataShuffler: Datagram channel is closed -- discarding packet."); } continue; } bridge = ConcurrentSet.getBridge(datagramChannel); if (bridge == null) { if (logger.isDebugEnabled()) { logger.debug("DataShuffler: Discarding packet: Could not find bridge"); } continue; } Sym packetReceivedSym = bridge.getReceiverSym(datagramChannel); /* * Note the original hold value and put the transmitter on which this packet was received on hold. */ if (packetReceivedSym == null || packetReceivedSym.getTransmitter() == null) { if (logger.isDebugEnabled()) { logger.debug( "DataShuffler: Could not find sym for inbound channel -- discarding packet"); } continue; } boolean holdValue = packetReceivedSym.getTransmitter().isOnHold(); packetReceivedSym.getTransmitter().setOnHold(true); InetSocketAddress remoteAddress = (InetSocketAddress) datagramChannel.receive(readBuffer); bridge.pakcetsReceived++; if (bridge.getState() != BridgeState.RUNNING) { if (logger.isDebugEnabled()) { logger.debug( "DataShuffler: Discarding packet: Bridge state is " + bridge.getState()); } packetReceivedSym.getTransmitter().setOnHold(holdValue); continue; } if (logger.isTraceEnabled()) { logger.trace("got something on " + datagramChannel.socket().getLocalPort()); } long stamp = getPacketCounter(); send(bridge, datagramChannel, remoteAddress, stamp, false); /* * Reset the old value. */ packetReceivedSym.getTransmitter().setOnHold(holdValue); } } } catch (Exception ex) { logger.error("Unexpected exception occured", ex); if (bridge != null && bridge.sessions != null) { for (Sym rtpSession : bridge.sessions) { rtpSession.close(); } } if (bridge != null) bridge.setState(BridgeState.TERMINATED); continue; } } }
From source file:voldemort.common.nio.AbstractSelectorManager.java
public void run() { threadName = Thread.currentThread().getName(); try {/* www . j a va2s.c o m*/ while (true) { if (isClosed.get()) { logger.debug("SelectorManager is closed, exiting"); break; } lastHeartBeatTimeMs = System.currentTimeMillis(); processEvents(); try { selectTimeMs = System.currentTimeMillis(); int selected = selector.select(SELECTOR_POLL_MS); selectTimeMs = System.currentTimeMillis() - selectTimeMs; selectCount = selected; if (isClosed.get()) { logger.debug("SelectorManager is closed, exiting"); break; } if (selected > 0) { processingTimeMs = System.currentTimeMillis(); Iterator<SelectionKey> i = selector.selectedKeys().iterator(); while (i.hasNext()) { SelectionKey selectionKey = i.next(); i.remove(); if (selectionKey.isValid() && (selectionKey.isConnectable() || selectionKey.isReadable() || selectionKey.isWritable())) { Runnable worker = (Runnable) selectionKey.attachment(); worker.run(); } } processingTimeMs = System.currentTimeMillis() - processingTimeMs; } } catch (ClosedSelectorException e) { logger.debug("SelectorManager is closed, exiting"); break; } catch (Throwable t) { if (logger.isEnabledFor(Level.ERROR)) logger.error(t.getMessage(), t); } } } catch (Throwable t) { if (logger.isEnabledFor(Level.ERROR)) logger.error(t.getMessage(), t); } finally { try { close(); } catch (Exception e) { if (logger.isEnabledFor(Level.ERROR)) logger.error(e.getMessage(), e); } } }
From source file:voldemort.common.nio.SelectorManagerWorker.java
public void run() { try {/*from w ww . ja va 2 s .c om*/ SelectionKey selectionKey = socketChannel.keyFor(selector); if (selectionKey.isConnectable()) connect(selectionKey); else if (selectionKey.isReadable()) read(selectionKey); else if (selectionKey.isWritable()) write(selectionKey); else if (!selectionKey.isValid()) throw new IllegalStateException("Selection key not valid for " + socketChannel.socket()); else throw new IllegalStateException( "Unknown state, not readable, writable, or valid for " + socketChannel.socket()); } catch (ClosedByInterruptException e) { reportException(e); close(); } catch (CancelledKeyException e) { close(); } catch (EOFException e) { // EOFException is expected, hence no logging, otherwise this block // could be combined with IOException reportException(e); close(); } catch (IOException e) { logger.info("Connection reset from " + socketChannel.socket() + " with message - " + e.getMessage()); reportException(e); close(); } catch (Throwable t) { logger.error("Caught throwable from " + socketChannel.socket(), t); close(); } }