/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.network.console.telnet;


import net.sourceforge.pain.util.*;

import java.net.*;
import java.util.*;


public class TelnetConsoleServer implements Runnable {

	private ServerSocket serverSocket;
	private int port;
	private Set connections = Collections.synchronizedSet(new HashSet());
	private boolean started;

	public TelnetConsoleServer(int port) {
		Log.info("TelnetConsoleServer created");
		this.port = port;
		Thread worker = new Thread(this);
		worker.setDaemon(true);
		worker.start();
	}

	public void run() {
		started = true;
		work();
	}

	public void work() {
		ConnectionChecker checker = new ConnectionChecker();
		Thread checkThread = new Thread(checker);
		checkThread.setDaemon(true);
		checkThread.start();
		try {
			Log.info("TelnetConsoleServer:creating server socket on port:" + port);
			serverSocket = new ServerSocket(port, 50, InetAddress.getByName("127.0.0.1"));
			serverSocket.setSoTimeout(0);
			Log.info("Server Initialised. listening...");
			do {
				try {
					Socket socket = serverSocket.accept();

					Log.debug("TelnetConsoleServer:connection accepted[" + connections.size() + "]:" + socket.getInetAddress());
					TelnetConsoleAdapter con = new TelnetConsoleAdapter(this, socket);
					connections.add(con);
					Thread worker = new Thread(con);
					worker.start();
				} catch (Exception e) {
					e.printStackTrace();
				}
			} while (started);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			checker.interrupted = true;
			checkThread.interrupt();
		}
	}

	protected void onClose(TelnetConsoleAdapter con) {
		Log.debug("TelnetConsoleServer:closing connection:[" + connections.size() + "]" + con.socket.getInetAddress());
		connections.remove(con);
	}

	public void stop() {
		started = false;
	}

	private class ConnectionChecker implements Runnable {

		public static final int CHECK_TIMEOUT = 5000;
		boolean interrupted = false;

		public void run() {
			while (!interrupted) {
				try {
					Collection c = new ArrayList(connections);
					for (Iterator it = c.iterator(); it.hasNext();) {
						TelnetConsoleAdapter con = (TelnetConsoleAdapter) it.next();
						try {
							Log.debug("TelnetConsoleServer:AYT to " + con.socket.getInetAddress());
						} catch (Exception e) {
							Log.error(e.getMessage(), e);
						}
						con.ping();
					}
					Thread.sleep(CHECK_TIMEOUT);
				} catch (InterruptedException e) {
					interrupted = true;
				} catch (Exception e) {
					Log.error(e.getMessage(), e);
				}
			}
		}
	}

}