
com.mckoi.database.jdbcserver.TCPServer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mckoisqldb Show documentation
Show all versions of mckoisqldb Show documentation
A full SQL database system with JDBC driver that can be embedded in a Java
application or operate as a stand-alone server with clients connecting via
TCP/IP.
The newest version!
/**
* com.mckoi.database.jdbcserver.TCPServer 21 Jul 2000
*
* Mckoi SQL Database ( http://www.mckoi.com/database )
* Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License Version 2 for more details.
*
* You should have received a copy of the GNU General Public License
* Version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Change Log:
*
*
*/
package com.mckoi.database.jdbcserver;
import com.mckoi.database.DatabaseSystem;
import com.mckoi.database.Database;
import com.mckoi.debug.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;
import java.io.IOException;
import java.util.HashMap;
import java.util.ResourceBundle;
/**
* A TCP/IP socket server that opens a single port and allows JDBC clients
* to connect through the port to talk with the database.
*
* @author Tobias Downer
*/
public final class TCPServer {
/**
* The parent Database object that describes everything about the
* database this TCP server is for.
*/
private Database database;
/**
* The ConnectionPoolServer that polls the ServerConnection for new commands
* to process.
*/
private ConnectionPoolServer connection_pool;
/**
* The ServerSocket object where the database server is bound.
*/
private ServerSocket server_socket;
/**
* The InetAddress the JDBC server is bound to.
*/
private InetAddress address;
/**
* The port the JDBC server is on.
*/
private int port;
/**
* The connection pool model used for this server.
*/
private String connection_pool_model;
/**
* Constructs the TCPServer over the given DatabaseSystem configuration.
*/
public TCPServer(Database database) {
this.database = database;
}
/**
* Returns a DebugLogger object that we can log debug messages to.
*/
public final DebugLogger Debug() {
return database.Debug();
}
/**
* Returns the port the JDBC server is on.
*/
public int getJDBCPort() {
return port;
}
/**
* Checks to see if there's already something listening on the jdbc
* port. Returns true if the jdbc port in the configuration is available,
* otherwise returns false.
*/
public boolean checkAvailable(InetAddress bind_address, int tcp_port) {
// MAJOR MAJOR HACK: We attempt to bind to the JDBC Port and if we get
// an error then most likely there's already a database running on this
// host.
int port = tcp_port;
// // Get information about how to set up the TCP port from the config
// // bundle.
// int port = Integer.parseInt(config.getString("jdbc_server_port"));
try {
// Bind the ServerSocket objects to the ports.
server_socket = new ServerSocket(port, 50, bind_address);
server_socket.close();
}
catch (IOException e) {
// If error then return false.
return false;
}
return true;
}
/**
* Starts the server running. This method returns immediately but spawns
* its own thread.
*/
public void start(InetAddress bind_address, int tcp_port,
String connection_pool_model) {
this.address = bind_address;
this.port = tcp_port;
this.connection_pool_model = connection_pool_model;
// // Get information about how to set up the TCP port from the config
// // bundle.
// port = Integer.parseInt(config.getString("jdbc_server_port"));
//
// // The 'tcp_connection_pool_thread_model' property determines the
// // connection pool object to use.
// connection_pool_model = "multi_threaded";
// try {
// String cptm = config.getString("tcp_connection_pool_thread_model");
// if (cptm.equalsIgnoreCase("single_threaded")) {
// connection_pool_model = "single_threaded";
// }
// // Multi-threaded if 'tcp_connection_pool_thread_model' is anything
// // other than 'single_threaded'
// }
// catch (java.util.MissingResourceException e) {
// // If no property in the config assume multi-threaded
// }
// Choose our connection pool implementation
if (connection_pool_model.equals("multi_threaded")) {
this.connection_pool = new MultiThreadedConnectionPoolServer(database);
}
else if (connection_pool_model.equals("single_threaded")) {
this.connection_pool = new SingleThreadedConnectionPoolServer(database);
}
try {
// Bind the ServerSocket object to the port.
server_socket = new ServerSocket(port, 50, bind_address);
server_socket.setSoTimeout(0);
}
catch (IOException e) {
Debug().writeException(e);
Debug().write(Lvl.ERROR, this,
"Unable to start a server socket on port: " + port);
throw new Error(e.getMessage());
}
// This thread blocks on the server socket.
Thread listen_thread = new Thread() {
public void run() {
try {
// Accept new connections and notify when one arrives
while(true) {
Socket s = server_socket.accept();
portConnection(s);
}
}
catch (IOException e) {
Debug().writeException(Lvl.WARNING, e);
Debug().write(Lvl.WARNING, this, "Socket listen thread died.");
}
}
};
// listen_thread.setDaemon(true);
listen_thread.setName("Mckoi - TCP/IP Socket Accept");
listen_thread.start();
}
/**
* Called whenever a new connection has been received on the port.
*/
private void portConnection(Socket socket) throws IOException {
// TCP connections are formatted as;
// 'TCP/[ip address]:[remote port]:[local port]'
String host_string = "TCP/" + socket.getInetAddress().getHostAddress() +
":" + socket.getPort() + "@" +
socket.getLocalAddress().getHostAddress() + ":" +
socket.getLocalPort();
// String host_string =
// "Host [" + socket.getInetAddress().getHostAddress() + "] " +
// "port=" + socket.getPort() + " localport=" + socket.getLocalPort();
// Make a new DatabaseInterface for this connection,
JDBCDatabaseInterface db_interface =
new JDBCDatabaseInterface(database, host_string);
TCPJDBCServerConnection connection =
new TCPJDBCServerConnection(db_interface, socket, Debug());
// Add the provider onto the queue of providers that are serviced by
// the server.
connection_pool.addConnection(connection);
}
/**
* Closes the JDBC Server.
*/
public void close() {
if (server_socket != null) {
try {
server_socket.close();
}
catch (IOException e) {
Debug().write(Lvl.ERROR, this, "Error closing JDBC Server.");
Debug().writeException(e);
}
}
connection_pool.close();
}
/**
* Returns human understandable information about the server.
*/
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("TCP JDBC Server (");
buf.append(connection_pool_model);
buf.append(") on ");
if (address != null) {
buf.append(address.getHostAddress());
buf.append(" ");
}
buf.append("port: ");
buf.append(getJDBCPort());
return new String(buf);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy