org.cristalise.kernel.utils.server.SimpleTCPIPServer Maven / Gradle / Ivy
/**
* This file is part of the CRISTAL-iSE kernel.
* Copyright (c) 2001-2015 The CRISTAL Consortium. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* http://www.fsf.org/licensing/licenses/lgpl.html
*/
package org.cristalise.kernel.utils.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import org.cristalise.kernel.utils.Logger;
public class SimpleTCPIPServer implements Runnable {
int port = 0;
int maxConn = 10;
Thread listener = null;
Class> handlerClass = null;
ServerSocket serverSocket = null;
boolean keepListening = true;
ArrayList currentHandlers = new ArrayList();
static short numberOfServers = 0;
public SimpleTCPIPServer(int port, Class> handlerClass, int maxConnections) {
this.port = port;
this.handlerClass = handlerClass;
this.maxConn = maxConnections;
numberOfServers++;
}
public void startListening() {
if(listener != null) return;
keepListening = true;
listener = new Thread(this);
listener.start();
}
public void stopListening() {
Logger.msg("SimpleTCPIPServer.stopListening() - Closing server for " + handlerClass.getName() +" on port "+ port);
keepListening = false;
for (SocketHandler thisHandler : currentHandlers) {
thisHandler.shutdown();
}
try {
if (serverSocket!=null) serverSocket.close();
}
catch (IOException e) { }
}
@Override
public void run() {
Thread.currentThread().setName("TCP/IP Server for class "+handlerClass.getName());
Socket connectionSocket = null;
try {
serverSocket = new ServerSocket(port);
if (port == 0) port = serverSocket.getLocalPort();
Logger.msg("SimpleTCPIPServer.run() - Created server for " + handlerClass.getName()+" on port "+port);
serverSocket.setSoTimeout(500);
SocketHandler freeHandler = null;
while(keepListening) {
if (freeHandler == null || freeHandler.isBusy()) {
ListIterator i = currentHandlers.listIterator();
try {
do {
freeHandler = i.next();
}
while (freeHandler.isBusy());
}
catch (NoSuchElementException e) {
// create new one
if (currentHandlers.size() < maxConn) {
freeHandler = (SocketHandler)handlerClass.newInstance();
currentHandlers.add(freeHandler);
}
else { // max handlers are created. wait for a while, then look again
Logger.warning("No free handlers left for "+handlerClass.getName()+" on port "+ port + "! Sleeping 2s.");
Thread.sleep(2000);
continue;
}
}
}
try {
connectionSocket = serverSocket.accept();
if (keepListening) {
Logger.msg("SimpleTCPIPServer: Connection to "+freeHandler.getName()+" from "+ connectionSocket.getInetAddress());
freeHandler.setSocket(connectionSocket);
new Thread(freeHandler).start();
}
}
catch (SocketTimeoutException ex1) { }// timeout just to check if we've been told to die
catch (SocketException ex1) { } // we were closed during shutdown
}
serverSocket.close();
Logger.msg("SimpleTCPIPServer: Server closed for " + handlerClass.getName() +" on port "+ port);
}
catch(Exception ex) {
Logger.error("SimpleTCPIPServer.run(): Fatal Error. Listener for '"+handlerClass.getName()+"' will stop.");
Logger.error(ex);
}
listener = null;
Logger.msg("SimpleTCPIPServer - Servers still running: "+--numberOfServers);
}
public int getPort() {
return port;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy