Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you are working with NIO, I would also suggest to use a Framework. I have been working with <a href="http://mina.apache.org/" rel="nofollow noreferrer">Apache Mina</a> and I would recommend it.</p> <p>As to the blocking IO, essentially you will need a Listener Thread that accepts incoming connections and spawns additional threads that will handle each connection. Here is an example of such a Listener code, as originally contributed to the Apache Felix Project. If you look for the complete but modified version, you can <a href="http://svn.apache.org/viewvc/felix/trunk/shell.remote/src/main/java/org/apache/felix/shell/remote/" rel="nofollow noreferrer">browse the source here</a>.</p> <p>e.g.</p> <pre><code> /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.felix.shell.remote; import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; /** * Implements a simple listener that will accept a single connection. * &lt;p/&gt; * * @author Dieter Wimberger (wimpi) */ class Listener { private int m_Port; private Thread m_ListenerThread; private boolean m_Stop = false; private ServerSocket m_ServerSocket; private AtomicInteger m_UseCounter; private int m_MaxConnections; /** * Activates this listener on a listener thread (telnetconsole.Listener). */ public void activate() { //configure from system property try { m_Port = Integer.parseInt( System.getProperty( "osgi.shell.telnet.port", "6666" ) ); } catch ( NumberFormatException ex ) { Activator.getServices().error( "Listener::activate()", ex ); } try { m_MaxConnections = Integer.parseInt( System.getProperty( "osgi.shell.telnet.maxconn", "2" ) ); } catch ( NumberFormatException ex ) { Activator.getServices().error( "Listener::activate()", ex ); } m_UseCounter = new AtomicInteger( 0 ); m_ListenerThread = new Thread( new Acceptor(), "telnetconsole.Listener" ); m_ListenerThread.start(); }//activate /** * Deactivates this listener. * &lt;p/&gt; * The listener's socket will be closed, which should cause an interrupt in the * listener thread and allow for it to return. The calling thread joins the listener * thread until it returns (to ensure a clean stop). */ public void deactivate() { try { m_Stop = true; //wait for the listener thread m_ServerSocket.close(); m_ListenerThread.join(); } catch ( Exception ex ) { Activator.getServices().error( "Listener::deactivate()", ex ); } }//deactivate /** * Class that implements the listener's accept logic as a &lt;tt&gt;Runnable&lt;/tt&gt;. */ private class Acceptor implements Runnable { /** * Listens constantly to a server socket and handles incoming connections. * One connection will be accepted and routed into the shell, all others will * be notified and closed. * &lt;p/&gt; * The mechanism that should allow the thread to unblock from the ServerSocket.accept() call * is currently closing the ServerSocket from another thread. When the stop flag is set, * this should cause the thread to return and stop. */ public void run() { try { /* A server socket is opened with a connectivity queue of a size specified in int floodProtection. Concurrent login handling under normal circumstances should be handled properly, but denial of service attacks via massive parallel program logins should be prevented with this. */ m_ServerSocket = new ServerSocket( m_Port, 1 ); do { try { Socket s = m_ServerSocket.accept(); if ( m_UseCounter.get() &gt;= m_MaxConnections ) { //reject with message PrintStream out = new PrintStream( s.getOutputStream() ); out.print( INUSE_MESSAGE ); out.flush(); //close out.close(); s.close(); } else { m_UseCounter.increment(); //run on the connection thread Thread connectionThread = new Thread( new Shell( s, m_UseCounter ) ); connectionThread.start(); } } catch ( SocketException ex ) { } } while ( !m_Stop ); } catch ( IOException e ) { Activator.getServices().error( "Listener.Acceptor::activate()", e ); } }//run }//inner class Acceptor private static final String INUSE_MESSAGE = "Connection refused.\r\n" + "All possible connections are currently being used.\r\n"; }//class Listener </code></pre> <p>You can find other examples <a href="http://jamod.cvs.sourceforge.net/viewvc/jamod/jamod/src/net/wimpi/modbus/net/ModbusTCPListener.java?revision=1.4&amp;view=markup" rel="nofollow noreferrer">here</a> and <a href="http://telnetd.svn.sourceforge.net/viewvc/telnetd/osgi/trunk/src/java/net/wimpi/telnetd/net/" rel="nofollow noreferrer">here</a>.</p> <p>Note that the advantage of NIO over the blocking model comes into play when you have more load. From a certain point on, the amount of extra work for Thread creation, management and context switching will limit your system performance. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload