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 + -
显示快捷键?