2011-02-15 19:37:35 +00:00
|
|
|
package zutil.net.threaded;
|
2010-01-31 18:10:00 +00:00
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
|
import java.net.Socket;
|
|
|
|
|
import java.security.KeyStoreException;
|
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
|
import java.security.NoSuchProviderException;
|
|
|
|
|
import java.security.cert.CertificateException;
|
2011-06-24 23:20:59 +00:00
|
|
|
import java.util.logging.Level;
|
|
|
|
|
import java.util.logging.Logger;
|
2010-01-31 18:10:00 +00:00
|
|
|
|
|
|
|
|
import javax.net.ssl.SSLServerSocketFactory;
|
|
|
|
|
|
2011-06-24 23:20:59 +00:00
|
|
|
import zutil.log.LogUtil;
|
2010-01-31 18:10:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2011-06-24 23:20:59 +00:00
|
|
|
* A simple network server that handles TCP communication
|
2010-01-31 18:10:00 +00:00
|
|
|
*
|
|
|
|
|
* @author Ziver
|
|
|
|
|
*/
|
|
|
|
|
public abstract class ThreadedTCPNetworkServer extends Thread{
|
2011-06-24 23:20:59 +00:00
|
|
|
public static final Logger logger = LogUtil.getLogger();
|
|
|
|
|
|
2010-01-31 18:10:00 +00:00
|
|
|
public final int port;
|
|
|
|
|
private File keyStore;
|
|
|
|
|
private String keyStorePass;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a new instance of the sever
|
|
|
|
|
*
|
2011-06-24 23:20:59 +00:00
|
|
|
* @param port The port that the server should listen to
|
2010-01-31 18:10:00 +00:00
|
|
|
*/
|
|
|
|
|
public ThreadedTCPNetworkServer(int port){
|
|
|
|
|
this(port, null, null);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Creates a new instance of the sever
|
|
|
|
|
*
|
2011-06-24 23:20:59 +00:00
|
|
|
* @param port The port that the server should listen to
|
|
|
|
|
* @param sslCert If this is not null then the server will use SSL connection with this keyStore file path
|
|
|
|
|
* @param sslCert If this is not null then the server will use a SSL connection with the given certificate
|
2010-01-31 18:10:00 +00:00
|
|
|
*/
|
|
|
|
|
public ThreadedTCPNetworkServer(int port, File keyStore, String keyStorePass){
|
|
|
|
|
this.port = port;
|
|
|
|
|
this.keyStorePass = keyStorePass;
|
|
|
|
|
this.keyStore = keyStore;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void run(){
|
|
|
|
|
ServerSocket ss = null;
|
|
|
|
|
try{
|
|
|
|
|
if(keyStorePass != null && keyStore != null){
|
|
|
|
|
registerCertificate(keyStore, keyStorePass);
|
|
|
|
|
ss = initSSL( port );
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
ss = new ServerSocket( port );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(true){
|
|
|
|
|
Socket s = ss.accept();
|
|
|
|
|
ThreadedTCPNetworkServerThread t = getThreadInstance( s );
|
|
|
|
|
if( t!=null )
|
|
|
|
|
new Thread( t ).start();
|
|
|
|
|
else{
|
2011-06-24 23:20:59 +00:00
|
|
|
logger.severe("Unable to instantiate ThreadedTCPNetworkServerThread, closing connection!");
|
2010-01-31 18:10:00 +00:00
|
|
|
s.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch(Exception e) {
|
2011-06-24 23:20:59 +00:00
|
|
|
logger.log(Level.SEVERE, null, e);
|
2010-01-31 18:10:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ss!=null ){
|
|
|
|
|
try{
|
|
|
|
|
ss.close();
|
2011-06-24 23:20:59 +00:00
|
|
|
}catch(IOException e){ logger.log(Level.SEVERE, null, e); }
|
2010-01-31 18:10:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This method returns an new instance of the ThreadedTCPNetworkServerThread
|
|
|
|
|
* that will handle the newly made connection, if an null value is returned
|
|
|
|
|
* then the ThreadedTCPNetworkServer will close the new connection.
|
|
|
|
|
*
|
2011-06-24 23:20:59 +00:00
|
|
|
* @param s is an new connection to an host
|
|
|
|
|
* @return a new instance of an thread or null
|
2010-01-31 18:10:00 +00:00
|
|
|
*/
|
|
|
|
|
protected abstract ThreadedTCPNetworkServerThread getThreadInstance( Socket s );
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initiates a SSLServerSocket
|
|
|
|
|
*
|
2011-06-24 23:20:59 +00:00
|
|
|
* @param port The port to listen to
|
|
|
|
|
* @return The SSLServerSocket
|
2010-01-31 18:10:00 +00:00
|
|
|
*/
|
|
|
|
|
private ServerSocket initSSL(int port) throws IOException{
|
|
|
|
|
SSLServerSocketFactory sslserversocketfactory =
|
|
|
|
|
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
|
|
|
|
|
return sslserversocketfactory.createServerSocket(port);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Registers the given cert file to the KeyStore
|
|
|
|
|
*
|
2011-06-24 23:20:59 +00:00
|
|
|
* @param certFile The cert file
|
2010-01-31 18:10:00 +00:00
|
|
|
*/
|
|
|
|
|
protected void registerCertificate(File keyStore, String keyStorePass) throws CertificateException, IOException, KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException{
|
|
|
|
|
System.setProperty("javax.net.ssl.keyStore", keyStore.getAbsolutePath());
|
|
|
|
|
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePass);
|
|
|
|
|
}
|
|
|
|
|
}
|