⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractlistener.java

📁 这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package net.sf.dz.daemon.tcp.server;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketException;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.TreeSet;import javax.net.ssl.SSLException;import org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.sem.SemaphoreGroup;import org.freehold.jukebox.service.ActiveService;import org.freehold.jukebox.service.PassiveService;import org.freehold.jukebox.service.ServiceUnavailableException;import net.sf.dz.util.HostHelper;import net.sf.dz.util.SSLContextFactory;import net.sf.dz.pnp.MulticastServer;import net.sf.dz.pnp.custom.SimpleBroadcastServer;import net.sf.dz.pnp.custom.SimpleMulticastServer;/** * The TCP connection listener. * * <p> * * Provides: * * <ul> * *     <li> Configuration; *     <li> Connection setup, including SSL; *     <li> Client handling logic; *     <li> Service announcements. * </ul> * * @author Copyright &copy; <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2004 * @version $Id: AbstractListener.java,v 1.2 2004/06/28 20:35:48 vtt Exp $ */abstract public class AbstractListener extends PassiveService {    /**     * Set of addresses to listen on.     *     * Empty set means that we're listening on all local addresses.     */    private Set addressSet;        /**     * The port to listen to.     */    private int port;        /**     * The port to broadcast on.     */    private int broadcastPort;        /**     * Is the connection requested to be secure.     */    private boolean secure;        /**     * Password for the key store.     *     * VT: Don't tell me it's insecure, just fix the implementation to be     * more secure, all right?     */    private String password;        /**     * The listener services.     */    private Set listenerSet = new TreeSet();        /**     * Set of active clients.     */    private Set clientSet = new HashSet();        /**     * Connection count.     */    protected int connectionCount = 0;        private MulticastServer multicastServer;        abstract protected LogChannel getLogChannel();        public final Iterator iterator() {            return clientSet.iterator();    }        protected final void configure() {            Configuration cf = getConfiguration();        String cfroot = getConfigurationRoot();                addressSet = new HashSet(cf.getList(cfroot + ".tcp.bind_address"));        port = cf.getInteger(cfroot + ".tcp.port", getDefaultListenPort());        broadcastPort = cf.getInteger(cfroot + ".tcp.broadcast_port", getDefaultBroadcastPort());                // VT: NOTE: Current default is insecure - less hassle for initial        // configuration                secure = cf.getBoolean(cfroot + ".tcp.secure", false);                if ( secure ) {                    password = cf.getString(cfroot + ".tcp.password");         }                complain(LOG_INFO, getLogChannel(), "Binding to: " + addressSet);                // Now, configure the subclass...                configure2();    }        abstract protected void configure2();        protected final void startup() throws Throwable {            // Check if we're configured        getConfiguration();                // Perform the startup actions for the subclasses first - it doesn't        // make any sense to open the connection listener if the subclass        // business logic determines that something's not right and we can't        // start                startup2();                // Let's see if we have any addresses configured. If we don't, it        // means that we'll listen on all local ports.                if ( addressSet.isEmpty() ) {                    complain(LOG_INFO, getLogChannel(), "Listening on all local addresses");                        Listener l = new Listener(null, port);            l.setLogger(getLogger());            if ( !l.start().waitFor() ) {                            complain(LOG_WARNING, getLogChannel(), "Failed to start listener on *");            } else {                            listenerSet.add(l);            }        } else {                    // Let's collect the list of existing network interfaces, their            // addresses and see if we're properly configured. If there's a            // mismatch, the bad address will be removed from addressSet. If it            // turns out that the addressSet is empty after verification is            // done, we refuse to start.                        Set validAddresses = HostHelper.getLocalAddresses();                        for ( Iterator i = addressSet.iterator(); i.hasNext(); ) {                            String address = i.next().toString();                InetAddress configuredAddress = InetAddress.getByName(address);                                if ( !validAddresses.contains(configuredAddress) ) {                                    complain(LOG_WARNING, getLogChannel(), "Address specified in the configuration is not locally present: " + address);                    i.remove();                    continue;                }                            Listener l = new Listener(InetAddress.getByName(address), port);                l.setLogger(getLogger());                                // VT: FIXME: It is possible to parallel the startups in order                // to get all the listeners up faster, but this will complicate                // the logic, so let's do it when it becomes *absolutely*                // necessary.                                if ( !l.start().waitFor() ) {                                    complain(LOG_WARNING, getLogChannel(), "Failed to start listener on '" + address + "'");                } else {                                    listenerSet.add(l);                }            }        }                if ( listenerSet.isEmpty() ) {                    throw new IllegalStateException("No listeners could be started");        }                // VT: FIXME: Make sure we include the server signature (bug        // #914695). I'd guess that it should be passed down to us in the        // constructor.                multicastServer = new SimpleBroadcastServer(new HashSet(addressSet), broadcastPort);        multicastServer.setLogger(getLogger());        multicastServer.announce(getAnnounce());        multicastServer.start();    }        /**     * Do a service specific startup.     */    abstract protected void startup2() throws Throwable;        /**     * Provide a service signature.     *     * This signature must uniquely identify the module for the purpose of     * broadcast announcement.     */    abstract protected String getServiceSignature();        /**     * Provide a reasonable default for the {@link #port port} to listen to.     */    abstract protected int getDefaultListenPort();    /**     * Provide a reasonable default for the {@link #port port} to broadcast on.     */    abstract protected int getDefaultBroadcastPort();        /**     * Syntax sugar to change an announce message.     *     * @param message Message to announce.     */    protected final void announce(String message) {            multicastServer.announce(message);    }        /**     * Get the message to announce to our clients.     */    protected synchronized String getAnnounce() {            // The only things that make sense to include into *our*        // announcement are:                // - The server signature (FIXME);        // -  the port to connect to;        // - whether the connection is expected to be secure.                // If the client is able to receive the broadcast, then they will        // get the broadcast source and use it as the other endpoint, and        // this is sufficient. If they don't get the broadcast, they can't        // see us anyway and therefore don't care about all the ports we're        // listening at.                return "/" + port + "/" + (secure ? "secure" : "insecure");    }    protected void shutdown(Throwable cause) throws Throwable {            complain(LOG_NOTICE, getLogChannel(), "Shutting down");                multicastServer.stop();            SemaphoreGroup stop = new SemaphoreGroup();            synchronized ( listenerSet ) {            for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                            Listener l = (Listener)i.next();                                stop.add(l.stop());                i.remove();            }        }        complain(LOG_INFO, getLogChannel(), "Shut down listeners");        synchronized ( clientSet ) {                    for ( Iterator i = clientSet.iterator(); i.hasNext(); ) {                            ConnectionHandler ch = (ConnectionHandler)i.next();                                ch.send("E Shutting down");                stop.add(ch.stop());                i.remove();            }        }                stop.waitForAll();        complain(LOG_INFO, getLogChannel(), "Shut down clients");                // Clean up the mess after the clients are gone                cleanup();                // Now let's shut down the subclasses                shutdown2(cause);    }        abstract protected void shutdown2(Throwable cause) throws Throwable;        abstract protected ConnectionHandler createHandler(Socket socket, BufferedReader br, PrintWriter pw);        /**     * Find out whether more than one connection is allowed.     *     * @return false if multiple connections are allowed.     */    abstract protected boolean isUnique();        /**     * Clean up after the last active connection is gone.     *     * This method must be idempotent.     */    abstract protected void cleanup() throws Throwable;        protected final class Listener extends ActiveService implements Comparable {            InetAddress addr;        int port;        ServerSocket ss;                public Listener(InetAddress addr, int port) {                    this.addr = addr;            this.port = port;        }                protected void startup() throws Throwable {                    try {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -