X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;ds=inline;f=serial%2Fserver%2FServer.java;h=36806d6b61924bd60d5d0d1d2c6afca68d878893;hb=HEAD;hp=04701590e1c669c7d2dd143e7c9d3e921052b5b5;hpb=3f57613b51ba7722919cad64485b5409b4df1937;p=fanfix.git diff --git a/serial/server/Server.java b/serial/server/Server.java deleted file mode 100644 index 0470159..0000000 --- a/serial/server/Server.java +++ /dev/null @@ -1,419 +0,0 @@ -package be.nikiroo.utils.serial.server; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; - -import be.nikiroo.utils.TraceHandler; - -/** - * This class implements a simple server that can listen for connections and - * send/receive objects. - *
- * Note: this {@link Server} has to be discarded after use (cannot be started - * twice). - * - * @author niki - */ -abstract class Server implements Runnable { - protected final String key; - protected long id = 0; - - private final String name; - private final Object lock = new Object(); - private final Object counterLock = new Object(); - - private ServerSocket ss; - private int port; - - private boolean started; - private boolean exiting = false; - private int counter; - - private long bytesReceived; - private long bytesSent; - - private TraceHandler tracer = new TraceHandler(); - - /** - * Create a new {@link ConnectActionServer} to handle a request. - * - * @param s - * the socket to service - * - * @return the action - */ - abstract ConnectActionServer createConnectActionServer(Socket s); - - /** - * Create a new server that will start listening on the network when - * {@link Server#start()} is called. - * - * @param port - * the port to listen on, or 0 to assign any unallocated port - * found (which can later on be queried via - * {@link Server#getPort()} - * @param key - * an optional key to encrypt all the communications (if NULL, - * everything will be sent in clear text) - * - * @throws IOException - * in case of I/O error - * @throws UnknownHostException - * if the IP address of the host could not be determined - * @throws IllegalArgumentException - * if the port parameter is outside the specified range of valid - * port values, which is between 0 and 65535, inclusive - */ - public Server(int port, String key) throws IOException { - this((String) null, port, key); - } - - /** - * Create a new server that will start listening on the network when - * {@link Server#start()} is called. - *
- * All the communications will happen in plain text. - * - * @param name - * the server name (only used for debug info and traces) - * @param port - * the port to listen on - * - * @throws IOException - * in case of I/O error - * @throws UnknownHostException - * if the IP address of the host could not be determined - * @throws IllegalArgumentException - * if the port parameter is outside the specified range of valid - * port values, which is between 0 and 65535, inclusive - */ - public Server(String name, int port) throws IOException { - this(name, port, null); - } - - /** - * Create a new server that will start listening on the network when - * {@link Server#start()} is called. - * - * @param name - * the server name (only used for debug info and traces) - * @param port - * the port to listen on - * @param key - * an optional key to encrypt all the communications (if NULL, - * everything will be sent in clear text) - * - * @throws IOException - * in case of I/O error - * @throws UnknownHostException - * if the IP address of the host could not be determined - * @throws IllegalArgumentException - * if the port parameter is outside the specified range of valid - * port values, which is between 0 and 65535, inclusive - */ - public Server(String name, int port, String key) throws IOException { - this.name = name; - this.port = port; - this.key = key; - this.ss = new ServerSocket(port); - - if (this.port == 0) { - this.port = this.ss.getLocalPort(); - } - } - - /** - * The traces handler for this {@link Server}. - * - * @return the traces handler - */ - public TraceHandler getTraceHandler() { - return tracer; - } - - /** - * The traces handler for this {@link Server}. - * - * @param tracer - * the new traces handler - */ - public void setTraceHandler(TraceHandler tracer) { - if (tracer == null) { - tracer = new TraceHandler(false, false, false); - } - - this.tracer = tracer; - } - - /** - * The name of this {@link Server} if any. - *
- * Used for traces and debug purposes only. - * - * @return the name or NULL - */ - public String getName() { - return name; - } - - /** - * Return the assigned port. - * - * @return the assigned port - */ - public int getPort() { - return port; - } - - /** - * The total amount of bytes received. - * - * @return the amount of bytes received - */ - public long getBytesReceived() { - return bytesReceived; - } - - /** - * The total amount of bytes sent. - * - * @return the amount of bytes sent - */ - public long getBytesSent() { - return bytesSent; - } - - /** - * Start the server (listen on the network for new connections). - *
- * Can only be called once. - *
- * This call is asynchronous, and will just start a new {@link Thread} on - * itself (see {@link Server#run()}). - */ - public void start() { - new Thread(this).start(); - } - - /** - * Start the server (listen on the network for new connections). - *
- * Can only be called once. - *
- * You may call it via {@link Server#start()} for an asynchronous call, too. - */ - @Override - public void run() { - ServerSocket ss = null; - boolean alreadyStarted = false; - synchronized (lock) { - ss = this.ss; - if (!started && ss != null) { - started = true; - } else { - alreadyStarted = started; - } - } - - if (alreadyStarted) { - tracer.error(name + ": cannot start server on port " + port - + ", it is already started"); - return; - } - - if (ss == null) { - tracer.error(name + ": cannot start server on port " + port - + ", it has already been used"); - return; - } - - try { - tracer.trace(name + ": server starting on port " + port + " (" - + (key != null ? "encrypted" : "plain text") + ")"); - - while (started && !exiting) { - count(1); - final Socket s = ss.accept(); - new Thread(new Runnable() { - @Override - public void run() { - ConnectActionServer action = null; - try { - action = createConnectActionServer(s); - action.connect(); - } finally { - count(-1); - if (action != null) { - bytesReceived += action.getBytesReceived(); - bytesSent += action.getBytesSent(); - } - } - } - }).start(); - } - - // Will be covered by @link{Server#stop(long)} for timeouts - while (counter > 0) { - Thread.sleep(10); - } - } catch (Exception e) { - if (counter > 0) { - onError(e); - } - } finally { - try { - ss.close(); - } catch (Exception e) { - onError(e); - } - - this.ss = null; - - started = false; - exiting = false; - counter = 0; - - tracer.trace(name + ": client terminated on port " + port); - } - } - - /** - * Will stop the server, synchronously and without a timeout. - */ - public void stop() { - tracer.trace(name + ": stopping server"); - stop(0, true); - } - - /** - * Stop the server. - * - * @param timeout - * the maximum timeout to wait for existing actions to complete, - * or 0 for "no timeout" - * @param wait - * wait for the server to be stopped before returning - * (synchronous) or not (asynchronous) - */ - public void stop(final long timeout, final boolean wait) { - if (wait) { - stop(timeout); - } else { - new Thread(new Runnable() { - @Override - public void run() { - stop(timeout); - } - }).start(); - } - } - - /** - * Stop the server (synchronous). - * - * @param timeout - * the maximum timeout to wait for existing actions to complete, - * or 0 for "no timeout" - */ - private void stop(long timeout) { - tracer.trace(name + ": server stopping on port " + port); - synchronized (lock) { - if (started && !exiting) { - exiting = true; - - try { - getConnectionToMe().connect(); - long time = 0; - while (ss != null && timeout > 0 && timeout > time) { - Thread.sleep(10); - time += 10; - } - } catch (Exception e) { - if (ss != null) { - counter = 0; // will stop the main thread - onError(e); - } - } - } - } - - // return only when stopped - while (started || exiting) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - } - } - - /** - * Return a connection to this server (used by the Exit code to send an exit - * message). - * - * @return the connection - * - * @throws UnknownHostException - * the host should always be NULL (localhost) - * @throws IOException - * in case of I/O error - */ - abstract protected ConnectActionClient getConnectionToMe() - throws UnknownHostException, IOException; - - /** - * Change the number of currently serviced actions. - * - * @param change - * the number to increase or decrease - * - * @return the current number after this operation - */ - private int count(int change) { - synchronized (counterLock) { - counter += change; - return counter; - } - } - - /** - * This method will be called on errors. - *
- * By default, it will only call the trace handler (so you may want to call - * super {@link Server#onError} if you override it). - * - * @param e - * the error - */ - protected void onError(Exception e) { - tracer.error(e); - } - - /** - * Return the next ID to use. - * - * @return the next ID - */ - protected synchronized long getNextId() { - return id++; - } - - /** - * Method called when - * {@link ServerObject#onRequest(ConnectActionServerObject, Object, long)} - * has successfully finished. - *
- * Can be used to know how much data was transmitted. - * - * @param id - * the ID used to identify the request - * @param bytesReceived - * the bytes received during the request - * @param bytesSent - * the bytes sent during the request - */ - @SuppressWarnings("unused") - protected void onRequestDone(long id, long bytesReceived, long bytesSent) { - } -}