Java:实现多线程Web服务器

时间:2015-04-06 18:02:59

标签: java multithreading

尝试使用this assignment进行练习。两个问题陷入困境。

  1. 在控制台上打印请求后,应该在哪里停止线程?稍后我会在发送回复后这样做。
  2. 我应该从哪里发送回复?我可以从processRequest()轻松完成。正在考虑是否有反馈发送HttpResponse。 可以从HttpRequest类本身发回响应吗?
  3. 代码

    主要课程

    public final class WebServer {
    
        public static void main(String[] args) throws Exception {
            int port = 1983;
            final ServerSocket server = new ServerSocket(port);
            System.out.println("Comes here");
            Socket client = null;
            while (true) {
                client = server.accept();
                System.out.println("Got the connection" + client.toString());
                final HttpRequest request = new HttpRequest(client);
                Thread thread = new Thread(request);
                thread.start();
    
            }
        }
    
    }
    

    HttpRequest.java

    final class HttpRequest implements Runnable {
    
        Socket socket;
    
        public HttpRequest(Socket socket) {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                processRequest();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private void processRequest() throws IOException {
            String headerline = null;
            DataOutputStream out = null;
            BufferedReader in = null;
            out = new DataOutputStream(socket.getOutputStream());
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
            while ((headerline = in.readLine()).length() != 0) {
                System.out.println(headerline);
            }
            out.close();
            in.close();
            socket.close();
        }
    
    }
    

2 个答案:

答案 0 :(得分:1)

  1. 一旦套接字关闭,线程就会终止。

  2. 要以这种形式输出到客户端,您必须生成自己的Http标头,该标头需要发送到客户端以及您发送给客户端的所有数据。为此,您可以:

    out.writeBytes(<HttpHeaderString>);

  3. 然后,对于您的文件,您可以执行以下操作:

            FileInputStream fileToClient;
            OutputStream toClient;
            byte[] buffer = new byte[2048];
            int bytes = 0;
    
            while ((bytes = fileToClient.read(buffer)) != -1){
                toClient.write(buffer, 0, bytes);
            }
    

答案 1 :(得分:1)

  1. 该页面提到了Thread类的实例,但理想情况下,您不会停止线程,而是将它们返回池中。这样你就不会为每个请求创建一个新线程,而是重用线程。

    pool = Executors.newFixedThreadPool(poolSize);

    while(true){       pool.execute(新的HttpRequest(客户端); }

  2. 你可以从任何地方做到只要保持对Socket的OutputStream的引用,不要忘记刷新它。

    至于命名,从请求对象发回响应有点尴尬。只需将您的HttpRequest重命名为HttpRequestHandler,它假定您将按照您喜欢的方式处理传入请求,并且应该没问题。