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

📄 server.java

📁 一些网上收集的或是作者本人写的值得推荐的源程序代码.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        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.
     *
     * All connections through the same port to this service share a single
     * Service object.  Thus, any state local to an individual connection must
     * be stored in local variables within the serve() method.  State that
     * should be global to all connections on the same port should be stored
     * in instance variables of the Service class.  If the same Service is
     * running on more than one port, there will typically be different
     * Service instances for each port.  Data that should be global to all
     * connections on any port should be stored in static variables.
     *
     * Note that implementations of this interface must have a no-argument 
     * constructor if they are to be dynamically instantiated by the main()
     * method of the Server class.
     **/
    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.  
     *
     * The recognized commands are:
     *   password: give password; authorization is required for most commands
     *   add:      dynamically add a named service on a specified port
     *   remove:   dynamically remove the service running on a specified port
     *   max:      change the current maximum connection limit.
     *   status:   display current services, connections, and connection limit
     *   help:     display a help message
     *   quit:     disconnect
     *
     * This service displays a prompt, and sends all of its output to the user
     * in capital letters.  Only one client is allowed to connect to this 
     * service at a time.
     **/
    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 + -