2015-04-06 124 views
0

嘗試在this assignment上練習。有兩個問題陷入困境。Java:實現多線程Web服務器

  1. 在控制檯上打印請求後,我應該在哪裏停止線程?稍後,我需要在發送回覆後這樣做。
  2. 從哪裏發回應答?我可以從processRequest()輕鬆完成。正在考慮是否無論如何發回HttpResponse。 從HttpRequest類本身發回響應可以嗎?

代碼

主要類

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(); 
    } 

} 

回答

1
  1. 線程將立即終止當插座關閉時。

  2. 要以這種形式輸出到客戶端,您必須生成您自己的Http標頭,需要發送給客戶端以及您發送給客戶端的所有數據。要做到這一點,你可以這樣做:

    out.writeBytes(<HttpHeaderString>);

然後爲您的文件,你可以這樣做:

 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. 頁提到Thread類的實例,但理想情況下,您不會停止線程,而是將它們還給游泳池。這樣你就不會爲每個請求創建一個新的線程,而是重用線程。

    pool = Executors.newFixedThreadPool(poolSize);

    ,而(真){ pool.execute(新的HttpRequest(客戶端);} 。

  2. 你可以做到這一點從任何地方只是不停參考Socket的OutputStream的,不要忘記刷新它

    至於命名,從請求對象發回響應有點麻煩,只需將HttpRequest重命名爲像HttpRequestHandler這樣的東西,它假定您可以按照您喜歡的方式處理傳入請求,並且應該沒問題。