X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fserial%2Fserver%2FServer.java;h=04701590e1c669c7d2dd143e7c9d3e921052b5b5;hb=5584adbbbf5444c0039fed2b35dc7d5bb57b71b1;hp=36806d6b61924bd60d5d0d1d2c6afca68d878893;hpb=79ce1a4973eba079ba819ba841d906de42f38e40;p=fanfix.git diff --git a/src/be/nikiroo/utils/serial/server/Server.java b/src/be/nikiroo/utils/serial/server/Server.java index 36806d6..0470159 100644 --- a/src/be/nikiroo/utils/serial/server/Server.java +++ b/src/be/nikiroo/utils/serial/server/Server.java @@ -3,13 +3,7 @@ package be.nikiroo.utils.serial.server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; -import java.util.ArrayList; -import java.util.List; - -import javax.net.ssl.SSLServerSocket; -import javax.net.ssl.SSLServerSocketFactory; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; +import java.net.UnknownHostException; import be.nikiroo.utils.TraceHandler; @@ -23,10 +17,10 @@ import be.nikiroo.utils.TraceHandler; * @author niki */ abstract class Server implements Runnable { - static private final String[] ANON_CIPHERS = getAnonCiphers(); + protected final String key; + protected long id = 0; private final String name; - private final boolean ssl; private final Object lock = new Object(); private final Object counterLock = new Object(); @@ -37,6 +31,9 @@ abstract class Server implements Runnable { private boolean exiting = false; private int counter; + private long bytesReceived; + private long bytesSent; + private TraceHandler tracer = new TraceHandler(); /** @@ -57,35 +54,70 @@ abstract class Server implements Runnable { * the port to listen on, or 0 to assign any unallocated port * found (which can later on be queried via * {@link Server#getPort()} - * @param ssl - * use a SSL connection (or not) + * @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, boolean ssl) throws IOException { - this((String) null, port, ssl); + 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 - * @param ssl - * use a SSL connection (or not) * * @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, boolean ssl) throws IOException { + 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.ssl = ssl; - this.ss = createSocketServer(port, ssl); + this.key = key; + this.ss = new ServerSocket(port); if (this.port == 0) { this.port = this.ss.getLocalPort(); @@ -135,6 +167,24 @@ abstract class Server implements Runnable { 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). *

@@ -180,12 +230,28 @@ abstract class Server implements Runnable { } try { - tracer.trace(name + ": server starting on port " + port); + tracer.trace(name + ": server starting on port " + port + " (" + + (key != null ? "encrypted" : "plain text") + ")"); while (started && !exiting) { count(1); - Socket s = ss.accept(); - createConnectActionServer(s).connectAsync(); + 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 @@ -258,8 +324,7 @@ abstract class Server implements Runnable { exiting = true; try { - new ConnectActionClientObject(createSocket(null, port, ssl)) - .connect(); + getConnectionToMe().connect(); long time = 0; while (ss != null && timeout > 0 && timeout > time) { Thread.sleep(10); @@ -272,29 +337,30 @@ abstract class Server implements Runnable { } } } + } - // only return when stopped - while (started || exiting) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } + // return only when stopped + while (started || exiting) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { } } } /** - * 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). + * Return a connection to this server (used by the Exit code to send an exit + * message). * - * @param e - * the error + * @return the connection + * + * @throws UnknownHostException + * the host should always be NULL (localhost) + * @throws IOException + * in case of I/O error */ - protected void onError(Exception e) { - tracer.error(e); - } + abstract protected ConnectActionClient getConnectionToMe() + throws UnknownHostException, IOException; /** * Change the number of currently serviced actions. @@ -304,7 +370,7 @@ abstract class Server implements Runnable { * * @return the current number after this operation */ - int count(int change) { + private int count(int change) { synchronized (counterLock) { counter += change; return counter; @@ -312,73 +378,42 @@ abstract class Server implements Runnable { } /** - * Create a {@link Socket}. - * - * @param host - * the host to connect to - * @param port - * the port to connect to - * @param ssl - * TRUE for SSL mode (or FALSE for plain text mode) - * - * @return the {@link Socket} + * 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). * - * @throws IOException - * in case of I/O error + * @param e + * the error */ - static Socket createSocket(String host, int port, boolean ssl) - throws IOException { - Socket s; - if (ssl) { - s = SSLSocketFactory.getDefault().createSocket(host, port); - ((SSLSocket) s).setEnabledCipherSuites(ANON_CIPHERS); - } else { - s = new Socket(host, port); - } - - return s; + protected void onError(Exception e) { + tracer.error(e); } /** - * Create a {@link ServerSocket}. - * - * @param port - * the port to accept connections on - * @param ssl - * TRUE for SSL mode (or FALSE for plain text mode) - * - * @return the {@link ServerSocket} + * Return the next ID to use. * - * @throws IOException - * in case of I/O error + * @return the next ID */ - static ServerSocket createSocketServer(int port, boolean ssl) - throws IOException { - ServerSocket ss; - if (ssl) { - ss = SSLServerSocketFactory.getDefault().createServerSocket(port); - ((SSLServerSocket) ss).setEnabledCipherSuites(ANON_CIPHERS); - } else { - ss = new ServerSocket(port); - } - - return ss; + protected synchronized long getNextId() { + return id++; } /** - * Return all the supported ciphers that do not use authentication. + * Method called when + * {@link ServerObject#onRequest(ConnectActionServerObject, Object, long)} + * has successfully finished. + *

+ * Can be used to know how much data was transmitted. * - * @return the list of such supported ciphers + * @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 */ - private static String[] getAnonCiphers() { - List anonCiphers = new ArrayList(); - for (String cipher : ((SSLSocketFactory) SSLSocketFactory.getDefault()) - .getSupportedCipherSuites()) { - if (cipher.contains("_anon_")) { - anonCiphers.add(cipher); - } - } - - return anonCiphers.toArray(new String[] {}); + @SuppressWarnings("unused") + protected void onRequestDone(long id, long bytesReceived, long bytesSent) { } }