serverconnection.java
来自「邮件服务器系统 支持SMTP POP3 是著名的Apache写 有一定的参考」· Java 代码 · 共 516 行 · 第 1/2 页
JAVA
516 行
.append(" is listening on ") .append(serverSocket.toString()); getLogger().debug(debugBuffer.toString()); } while( !Thread.currentThread().interrupted() && null != serverConnectionThread ) { try { Socket clientSocket = null; try { clientSocket = serverSocket.accept(); } catch( InterruptedIOException iioe ) { // This exception is expected upon ServerConnection shutdown. // See the POLLING_INTERVAL comment continue; } catch( IOException se ) { if (ioExceptionCount > 0) { getLogger().error( "Fatal exception while listening on server socket. Terminating connection.", se ); break; } else { continue; } } catch( SecurityException se ) { getLogger().error( "Fatal exception while listening on server socket. Terminating connection.", se ); break; } ClientConnectionRunner runner = null; synchronized (clientConnectionRunners) { if ((maxOpenConn > 0) && (clientConnectionRunners.size() >= maxOpenConn)) { if (getLogger().isWarnEnabled()) { getLogger().warn("Maximum number of open connections exceeded - refusing connection. Current number of connections is " + clientConnectionRunners.size()); if (getLogger().isWarnEnabled()) { Iterator runnerIterator = clientConnectionRunners.iterator(); getLogger().info("Connections: "); while( runnerIterator.hasNext() ) { getLogger().info(" " + ((ClientConnectionRunner)runnerIterator.next()).toString()); } } } try { clientSocket.close(); } catch (IOException ignored) { // We ignore this exception, as we already have an error condition. } continue; } else { clientSocket.setSoTimeout(socketTimeout); runner = addClientConnectionRunner(); runner.setSocket(clientSocket); } } setupLogger( runner ); try { connThreadPool.execute( runner ); } catch (Exception e) { // This error indicates that the underlying thread pool // is out of threads. For robustness, we catch this and // cleanup getLogger().error("Internal error - insufficient threads available to service request. " + Thread.activeCount() + " threads in service request pool.", e); try { clientSocket.close(); } catch (IOException ignored) { // We ignore this exception, as we already have an error condition. } // In this case, the thread will not remove the client connection runner, // so we must. removeClientConnectionRunner(runner); } } catch( IOException ioe ) { getLogger().error( "Exception accepting connection", ioe ); } catch( Throwable e ) { getLogger().error( "Exception executing client connection runner: " + e.getMessage(), e ); } } synchronized( this ) { serverConnectionThread = null; Thread.currentThread().interrupted(); notifyAll(); } } /** * An inner class to provide the actual body of the thread of execution * that occurs upon a client connection. * */ class ClientConnectionRunner extends AbstractLogEnabled implements Component, Poolable, Runnable { /** * The Socket that this client connection is using for transport. */ private Socket clientSocket; /** * The thread of execution associated with this client connection. */ private Thread clientSocketThread; /** * Returns string for diagnostic logging */ public String toString() { return getClass().getName() + " for " + clientSocket + " on " + clientSocketThread; } public ClientConnectionRunner() { } /** * The dispose operation that terminates the runner. Should only be * called by the ServerConnection that owns the ClientConnectionRunner */ public void dispose() { synchronized( this ) { if (null != clientSocketThread) { // Execution of this block means that the run() method // hasn't finished yet. So we interrupt the thread // to terminate run() and wait for the run() method // to finish. The notifyAll() at the end of run() will // wake this thread and allow dispose() to end. clientSocketThread.interrupt(); clientSocketThread = null; try { wait(); } catch (InterruptedException ie) { // Expected - return from the method } } } } /** * Sets the socket for a ClientConnectionRunner. * * @param socket the client socket associated with this ClientConnectionRunner */ public void setSocket(Socket socket) { clientSocket = socket; } /** * Provides the body for the thread of execution dealing with a particular client * connection. An appropriate ConnectionHandler is created, applied, executed, * and released. */ public void run() { ConnectionHandler handler = null; try { clientSocketThread = Thread.currentThread(); handler = ServerConnection.this.handlerFactory.createConnectionHandler(); String connectionString = null; if( getLogger().isDebugEnabled() ) { connectionString = getConnectionString(); String message = "Starting " + connectionString; getLogger().debug( message ); } handler.handleConnection(clientSocket); if( getLogger().isDebugEnabled() ) { String message = "Ending " + connectionString; getLogger().debug( message ); } } catch( Throwable e ) { getLogger().error( "Error handling connection", e ); } finally { // Close the underlying socket try { if (clientSocket != null) { clientSocket.close(); } } catch( IOException ioe ) { getLogger().warn( "Error shutting down connection", ioe ); } clientSocket = null; // Null out the thread, notify other threads to encourage // a context switch synchronized( this ) { clientSocketThread = null; Thread.currentThread().interrupted(); // Release the handler and kill the reference to the handler factory // // This needs to be done after the clientSocketThread is nulled out, // otherwise we could trash a reused ClientConnectionRunner if (handler != null) { ServerConnection.this.handlerFactory.releaseConnectionHandler( handler ); handler = null; } // Remove this runner from the list of active connections. ServerConnection.this.removeClientConnectionRunner(this); notifyAll(); } } } /** * Helper method to return a formatted string with connection transport information. * * @return a formatted string */ private String getConnectionString() { if (clientSocket == null) { return "invalid socket"; } StringBuffer connectionBuffer = new StringBuffer(256) .append("connection on ") .append(clientSocket.getLocalAddress().getHostAddress().toString()) .append(":") .append(clientSocket.getLocalPort()) .append(" from ") .append(clientSocket.getInetAddress().getHostAddress().toString()) .append(":") .append(clientSocket.getPort()); return connectionBuffer.toString(); } } /** * The factory for producing handlers. */ private class ClientConnectionRunnerFactory implements ObjectFactory { /** * @see org.apache.avalon.excalibur.pool.ObjectFactory#newInstance() */ public Object newInstance() throws Exception { return new ClientConnectionRunner(); } /** * @see org.apache.avalon.excalibur.pool.ObjectFactory#getCreatedClass() */ public Class getCreatedClass() { return ClientConnectionRunner.class; } /** * @see org.apache.avalon.excalibur.pool.ObjectFactory#decommision(Object) */ public void decommission( Object object ) throws Exception { return; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?