⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxyserver.java

📁 一个用JAVA写的代理服务器的实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		" for service " + service.getClass().getName());	    // And start the Connection thread to provide the service	    c.start();	}    }    /**     * A Connection thread calls this method just before it exits.  It removes     * the specified Connection from the set of connections.     **/    protected synchronized void endConnection(Connection c) {	connections.remove(c);	log("Connection to " + c.client.getInetAddress().getHostAddress() +	    ":" + c.client.getPort() + " closed.");    }    /** Change the current connection limit */    public synchronized void setMaxConnections(int max) {	maxConnections = max;    }    /**     * This method displays status information about the server on the     * specified stream.  It can be used for debugging, and is used by the     * Control service later in this example.     **/    public synchronized void displayStatus(PrintWriter out) {	// Display a list of all Services that are being provided	Iterator keys = services.keySet().iterator();	while(keys.hasNext()) {	    Integer port = (Integer) keys.next();	    Listener listener =	(Listener) services.get(port);	    out.print("SERVICE " + listener.service.getClass().getName()		      + " ON PORT " + port + "\n");	}		// Display the current connection limit	out.print("MAX CONNECTIONS: " + maxConnections + "\n");	// Display a list of all current connections	Iterator conns = connections.iterator();	while(conns.hasNext()) {	    Connection c = (Connection)conns.next();	    out.print("CONNECTED TO " +		      c.client.getInetAddress().getHostAddress() +		      ":" + c.client.getPort() + " ON PORT " +		      c.client.getLocalPort() + " FOR SERVICE " +		      c.service.getClass().getName() + "\n");	}    }    /**     * This class is a subclass of Thread that handles an individual     * connection between a client and a Service provided by this server.     * Because each such connection has a thread of its own, each Service can     * have multiple connections pending at once.  Despite all the other     * threads in use, this is the key feature that makes this a     * multi-threaded server implementation.     **/    public class Connection extends Thread {        Socket client;     // The socket to talk to the client through        Service service;   // The service being provided to that client	        /**	 * This constructor just saves some state and calls the superclass	 * constructor to create a thread to handle the connection.  Connection	 * objects are created by Listener threads.  These threads are part of	 * the server's ThreadGroup, so all Connection threads are part of that	 * group, too.	 **/        public Connection(Socket client, Service service) {            super("Server.Connection:" +		  client.getInetAddress().getHostAddress() +		  ":" + client.getPort());            this.client = client;            this.service = service;        }	        /**	 * This is the body of each and every Connection thread.	 * All it does is pass the client input and output streams to the	 * serve() method of the specified Service object.  That method is	 * responsible for reading from and writing to those streams to	 * provide the actual service.  Recall that the Service object has	 * been passed from the Server.addService() method to a Listener	 * object to the addConnection() method to this Connection object, and	 * is now finally being used to provide the service.  Note that just	 * before this thread exits it always calls the endConnection() method	 * to remove itself from the set of connections	 **/        public void run() {            try {                 InputStream in = client.getInputStream();                OutputStream out = client.getOutputStream();                service.serve(in, out);            }             catch (IOException e) {log(e);}            finally { endConnection(this); }        }    }        /**     * Here is the Service interface that we have seen so much of.  It defines     * only a single method which is invoked to provide the service.  serve()     * will be passed an input stream and an output stream to the client.  It     * should do whatever it wants with them, and should close them before     * returning.          **/    public interface Service {        public void serve(InputStream in, OutputStream out) throws IOException;    }    /**     * A very simple service.  It displays the current time on the server     * to the client, and closes the connection.     **/    public static class Time implements Service {        public void serve(InputStream i, OutputStream o) throws IOException {            PrintWriter out = new PrintWriter(o);            out.print(new Date() + "\n");            out.close();            i.close();        }    }        /**     * This is another example service.  It reads lines of input from the     * client, and sends them back, reversed.  It also displays a welcome     * message and instructions, and closes the connection when the user      * enters a '.' on a line by itself.     **/    public static class Reverse implements Service {        public void serve(InputStream i, OutputStream o) throws IOException {            BufferedReader in = new BufferedReader(new InputStreamReader(i));            PrintWriter out =                 new PrintWriter(new BufferedWriter(new OutputStreamWriter(o)));            out.print("Welcome to the line reversal server.\n");            out.print("Enter lines.  End with a '.' on a line by itself.\n");            for(;;) {                out.print("> ");                out.flush();                String line = in.readLine();                if ((line == null) || line.equals(".")) break;                for(int j = line.length()-1; j >= 0; j--)                    out.print(line.charAt(j));                out.print("\n");            }            out.close();            in.close();        }    }        /**     * This service is an HTTP mirror, just like the HttpMirror class     * implemented earlier in this chapter.  It echos back the client's     * HTTP request     **/    public static class HTTPMirror implements Service {        public void serve(InputStream i, OutputStream o) throws IOException {            BufferedReader in = new BufferedReader(new InputStreamReader(i));            PrintWriter out = new PrintWriter(o);            out.print("HTTP/1.0 200 \n");            out.print("Content-Type: text/plain\n\n");            String line;            while((line = in.readLine()) != null) {                if (line.length() == 0) break;                out.print(line + "\n");            }            out.close();            in.close();        }    }        /**     * This service demonstrates how to maintain state across connections by     * saving it in instance variables and using synchronized access to those     * variables.  It maintains a count of how many clients have connected and     * tells each client what number it is     **/    public static class UniqueID implements Service {        public int id=0;        public synchronized int nextId() { return id++; }        public void serve(InputStream i, OutputStream o) throws IOException {            PrintWriter out = new PrintWriter(o);            out.print("You are client #: " + nextId() + "\n");            out.close();            i.close();        }    }        /**     * This is a non-trivial service.  It implements a command-based protocol     * that gives password-protected runtime control over the operation of the      * server.  See the main() method of the Server class to see how this     * service is started.            **/    public static class Control implements Service {        Server server;             // The server we control        String password;           // The password we require        boolean connected = false; // Whether a client is already connected	        /**	 * Create a new Control service.  It will control the specified Server	 * object, and will require the specified password for authorization	 * Note that this Service does not have a no argument constructor,	 * which means that it cannot be dynamically instantiated and added as	 * the other, generic services above can be.	 **/        public Control(Server server, String password) {            this.server = server;            this.password = password;        }        /**	 * This is the serve method that provides the service.  It reads a	 * line the client, and uses java.util.StringTokenizer to parse it	 * into commands and arguments.  It does various things depending on	 * the command.	 **/        public void serve(InputStream i, OutputStream o) throws IOException {            // Setup the streams            BufferedReader in = new BufferedReader(new InputStreamReader(i));            PrintWriter out = new PrintWriter(o);            String line;  // For reading client input lines	    // Has the user has given the password yet?            boolean authorized = false;             // If there is already a client connected to this service, display            // a message to this client and close the connection.  We use a            // synchronized block to prevent a race condition.            synchronized(this) {                 if (connected) {                     out.print("ONLY ONE CONTROL CONNECTION ALLOWED.\n");                    out.close();                    return;                }                else connected = true;            }	    // This is the main loop: read a command, parse it, and handle it            for(;;) {  // infinite loop                out.print("> ");           // Display a prompt                out.flush();               // Make it appear right away                line = in.readLine();      // Get the user's input                if (line == null) break;   // Quit if we get EOF.                try {                    // Use a StringTokenizer to parse the user's command                    StringTokenizer t = new StringTokenizer(line);                    if (!t.hasMoreTokens()) continue;  // if input was empty                    // Get first word of the input and convert to lower case                    String command = t.nextToken().toLowerCase();                     // Now compare to each of the possible commands, doing the                    // appropriate thing for each command                    if (command.equals("password")) {  // Password command                        String p = t.nextToken();      // Get the next word                        if (p.equals(this.password)) { // Is it the password?                            out.print("OK\n");         // Say so                            authorized = true;         // Grant authorization                        }                        else out.print("INVALID PASSWORD\n"); // Otherwise fail                    }                    else if (command.equals("add")) {  // Add Service command                        // Check whether password has been given                        if (!authorized) out.print("PASSWORD REQUIRED\n");                         else {                            // Get the name of the service and try to                            // dynamically load and instantiate it.                            // Exceptions will be handled below                            String serviceName = t.nextToken();                            Class serviceClass = Class.forName(serviceName);                            Service service;                            try {				service = (Service)serviceClass.newInstance();			    }                            catch (NoSuchMethodError e) {                                throw new IllegalArgumentException(					        "Service must have a " +						"no-argument constructor");                            }                            int port = Integer.parseInt(t.nextToken());                            // If no exceptions occurred, add the service                            server.addService(service, port);                            out.print("SERVICE ADDED\n");    // acknowledge                        }                    }                    else if (command.equals("remove")) { // Remove service                        if (!authorized) out.print("PASSWORD REQUIRED\n");                        else {                            int port = Integer.parseInt(t.nextToken());                             server.removeService(port); // remove the service                            out.print("SERVICE REMOVED\n"); // acknowledge                        }                    }                    else if (command.equals("max")) { // Set connection limit                        if (!authorized) out.print("PASSWORD REQUIRED\n");                        else {                            int max = Integer.parseInt(t.nextToken());                             server.setMaxConnections(max);                             out.print("MAX CONNECTIONS CHANGED\n");                        }                    }                    else if (command.equals("status")) { // Status Display                        if (!authorized) out.print("PASSWORD REQUIRED\n");			else server.displayStatus(out);                    }                    else if (command.equals("help")) {  // Help command                        // Display command syntax.  Password not required                        out.print("COMMANDS:\n" + 				  "\tpassword <password>\n" +				  "\tadd <service> <port>\n" +				  "\tremove <port>\n" +				  "\tmax <max-connections>\n" +				  "\tstatus\n" +				  "\thelp\n" + 				  "\tquit\n");                    }                    else if (command.equals("quit")) break; // Quit command.                    else out.print("UNRECOGNIZED COMMAND\n"); // Error		}                catch (Exception e) {                    // If an exception occurred during the command, print an                    // error message, then output details of the exception.                    out.print("ERROR WHILE PARSING OR EXECUTING COMMAND:\n" +			      e + "\n");                }            }            // Finally, when the loop command loop ends, close the streams            // and set our connected flag to false so that other clients can            // now connect.            connected = false;            out.close();            in.close();        }        }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -