/* * Copyright 1999-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @version $Id: JFCtest.java 165001 2005-04-27 16:01:42Z jfclere $ */ import java.io.*; import java.net.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.Vector; public class JFCtest implements Runnable { private ServerSocket server=null; private Thread thread=null; private boolean stopping=false; private Vector handlers=null; public static native void toto(); public JFCtest() { super(); System.err.println("JFCtest: instance "+this.hashCode()+ " created"); this.handlers=new Vector(); } protected void finalize() { System.err.println("JFCtest: instance "+this.hashCode()+ " garbage collected"); } /** * init and destroy were added in jakarta-tomcat-daemon. */ public void init() throws Exception { System.err.println("JFCtest: instance "+this.hashCode()+ " init"); int port=1200; /* Dump a message */ System.err.println("JFCtest: loading on port "+port); this.server=new ServerSocket(port); this.thread=new Thread(this); } public void start() { /* Dump a message */ System.err.println("JFCtest: starting"); /* Start */ this.thread.start(); } public void stop() throws IOException, InterruptedException { /* Dump a message */ System.err.println("JFCtest: stopping"); /* Close the ServerSocket. This will make our thread to terminate */ this.stopping=true; // this.server.setSoTimeout(10); System.err.println("JFCtest: stopping: before close"); // this.thread.interrupt(); this.server.close(); System.err.println("JFCtest: stopping: after close"); /* Wait for the main thread to exit and dump a message */ try { this.thread.join(5000); } catch (InterruptedException e) { } System.err.println("JFCtest: stopped"); } public void destroy() { System.err.println("JFCtest: instance "+this.hashCode()+ " destroy"); } public void run() { int number=0; System.err.println("JFCtest: started acceptor loop"); try { while(!this.stopping) { Socket socket=this.server.accept(); Handler handler=new Handler(socket,this); handler.setConnectionNumber(number++); new Thread(handler).start(); } } catch (IOException e) { /* Don't dump any error message if we are stopping. A IOException is generated when the ServerSocket is closed in stop() */ if (!this.stopping) e.printStackTrace(System.err); e.printStackTrace(System.err); } /* Terminate all handlers that at this point are still open */ Enumeration openhandlers=this.handlers.elements(); while (openhandlers.hasMoreElements()) { Handler handler=(Handler)openhandlers.nextElement(); System.err.println("JFCtest: dropping connection "+ handler.getConnectionNumber()); handler.close(); } System.err.println("JFCtest: exiting acceptor loop"); } protected void addHandler(Handler handler) { synchronized (handler) { this.handlers.add(handler); } } protected void removeHandler(Handler handler) { synchronized (handler) { this.handlers.remove(handler); } } public static class Handler implements Runnable { private JFCtest parent=null; private Socket socket=null; private int number=0; public Handler(Socket s, JFCtest p) { super(); this.socket=s; this.parent=p; } public void run() { this.parent.addHandler(this); System.err.println("JFCtest: connection "+this.number+ " opened from "+this.socket.getInetAddress()); try { InputStream in=this.socket.getInputStream(); OutputStream out=this.socket.getOutputStream(); handle(in,out); this.socket.close(); } catch (IOException e) { e.printStackTrace(System.err); } System.err.println("JFCtest: connection "+this.number+ " closed"); this.parent.removeHandler(this); } public void close() { try { this.socket.close(); } catch (IOException e) { e.printStackTrace(System.err); } } public void setConnectionNumber(int number) { this.number=number; } public int getConnectionNumber() { return(this.number); } public void handle(InputStream in, OutputStream os) { PrintStream out=null; try { out=new PrintStream(os, true, "US-ASCII"); } catch (UnsupportedEncodingException ex) { out=new PrintStream(os); } while(true) { try { /* If we don't have data in the System InputStream, we want to ask to the user for an option. */ if (in.available()==0) { out.println(); out.println("Please select one of the following:"); out.println(" 1) Shutdown"); out.println(" 2) Disconnect"); out.print("Your choiche: "); } /* Read an option from the client */ int x=in.read(); switch (x) { /* If the socket was closed, we simply return */ case -1: return; /* Attempt to shutdown */ case '1': out.println("Attempting a shutdown..."); try { this.parent.stop(); } catch (Exception e) { out.println(); out.println("Can't shutdown now"); e.printStackTrace(out); } break; /* Disconnect */ case '2': out.println("Disconnecting..."); return; /* Discard any carriage return / newline characters */ case '\r': case '\n': break; /* We got something that we weren't supposed to get */ default: out.println("Unknown option '"+(char)x+"'"); break; } /* If we get an IOException we return (disconnect) */ } catch (IOException e) { System.err.println("JFCtest: IOException in "+ "connection "+ this.getConnectionNumber()); return; } } } } public static void main(String[] args) throws Exception { JFCtest mytest = new JFCtest(); mytest.init(); mytest.start(); } }