/** * <pre> * This program is free software; you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * </pre> */ package com.meidusa.amoeba.net; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import org.apache.log4j.Level; import org.apache.log4j.Logger; /** * ָ��һ���˿�,����һ��serverSocket. ����ServerSocket��������Connection������� * * @author <a href=mailto:piratebase@sina.com>Struct chen</a> */ public class ServerableConnectionManager extends AuthingableConnectionManager { protected static Logger log = Logger.getLogger(ServerableConnectionManager.class); protected int port; protected ServerSocketChannel ssocket; protected String ipAddress; protected ConnectionFactory connFactory; public ServerableConnectionManager() throws IOException{ } public ServerableConnectionManager(String name, int port) throws IOException{ super(name); this.port = port; } /** * * @param name "Aladdin proxy Server" * @param ipAddress Aladdin proxy��ip * @param port Aladdin proxy��ip port * @throws IOException */ public ServerableConnectionManager(String name, String ipAddress, int port) throws IOException{ super(name); this.port = port; this.ipAddress = ipAddress; } /** * Amoeba Proxy Server�����ӹ�����ʵ���Ͼ���Ӧ�ó�����Amoeba Proxy Server���ӵ�user,pwd�� * @param connFactory */ public void setConnectionFactory(ConnectionFactory connFactory) { this.connFactory = connFactory; if (connFactory instanceof AbstractConnectionFactory) { AbstractConnectionFactory afactory = (AbstractConnectionFactory) connFactory; if (afactory.getConnectionManager() == null) { afactory.setConnectionManager(this); } } } // documentation inherited protected void willStart() { super.willStart(); try { // create a listening socket and add it to the select set ssocket = ServerSocketChannel.open(); ssocket.configureBlocking(false); InetSocketAddress isa = null; if (ipAddress != null) { isa = new InetSocketAddress(ipAddress, port); } else { isa = new InetSocketAddress(port); } ssocket.socket().bind(isa); registerServerChannel(ssocket); Level level = log.getLevel(); log.setLevel(Level.INFO); /** * ��ִ��amoeba start����󣬻���dos���������λ��������� * 2012-03-08 13:12:39,234 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:36190. */ log.info("Server listening on " + isa + "."); log.setLevel(level); } catch (IOException ioe) { /** * ��ִ��amoeba start�����������ڰ�amoba.xml�е�amoeba��ip�޸��ˣ����������������log * 2012-03-09 19:41:09,687 ERROR net.ServerableConnectionManager - Failure listening to socket on port '8066'. */ log.error("Failure listening to socket on port '" + port + "'.", ioe); System.exit(-1); } } protected void registerServerChannel(final ServerSocketChannel listener) throws IOException { // register this listening socket and map its select key to a net event // handler that will // accept new connections NetEventHandler serverNetEvent = new NetEventHandler() { private SelectionKey key; public int handleEvent(long when) { acceptConnection(listener); return 0; } public boolean checkIdle(long now) { return false; // we're never idle } public SelectionKey getSelectionKey() { return key; } public void setSelectionKey(SelectionKey key) { this.key = key; } public boolean doWrite() { return true; } }; SelectionKey sk = listener.register(_selector, SelectionKey.OP_ACCEPT, serverNetEvent); serverNetEvent.setSelectionKey(sk); postRegisterNetEventHandler(serverNetEvent, SelectionKey.OP_ACCEPT); } protected void acceptConnection(ServerSocketChannel listener) { SocketChannel channel = null; try { channel = listener.accept(); if (channel == null) { log.info("Psych! Got ACCEPT_READY, but no connection."); return; } if (!(channel instanceof SelectableChannel)) { try { log.warn("Provided with un-selectable socket as result of accept(), can't " + "cope [channel=" + channel + "]."); } catch (Error err) { log.warn("Un-selectable channel also couldn't be printed."); } // stick a fork in the socket channel.socket().close(); return; } connFactory.createConnection(channel, System.currentTimeMillis()); // this.postRegisterNetEventHandler(connection,SelectionKey.OP_READ); } catch (Exception e) { if (channel != null) { try { channel.socket().close(); } catch (IOException ioe) { log.warn("Failed closing aborted connection: " + ioe); } } } } public void closeAll() { super.closeAll(); try { ssocket.close(); } catch (IOException e) { } } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getIpAddress() { return ipAddress; } public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; } }