2011-10-19 61 views
1

我試圖製作一個簡單的HTML服務器,它將從我的瀏覽器讀取請求,解析請求中的請求文件,然後將相應的HTML提供給瀏覽器。我需要能夠處理多個請求,所以我現在有一個Server類充當另一個可運行類RequestHandler的父類。每次在服務器上建立連接時,都會運行可運行類RequestHandler的新實例。從本地服務器上的瀏覽器解析HTTP請求:Java

package server; 

import java.io.IOException; 
import java.net.ServerSocket; 

public class Server { 

    public static void main(String[] args){ 
     try{ 
      ServerSocket serverSocket = new ServerSocket(8000); 

      for(;;){ 
       Object block = new Object(); 
       RequestHandler handler = new RequestHandler(block, serverSocket); 
       handler.start(); 

       try{ 
        synchronized(block){ 
         System.out.println("Server thread paused..."); 
         block.wait(); 
         System.out.println("Server thread creating new RequestHandler..."); 
        } 
       }catch(InterruptedException e){ 
        System.out.println("Can't be interrupted!"); 
        e.printStackTrace(); 
       } 
      } 

     }catch(IOException e){ 
      System.out.println("IOException!"); 
      e.printStackTrace(); 
     } 
    } 
} 

package server; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class RequestHandler extends Thread { 

    Object block; 
    ServerSocket serverSocket; 
    BufferedReader socketReader; 
    PrintWriter socketWriter; 

    public RequestHandler(Object block, ServerSocket serverSocket){ 
     this.block = block; 
     this.serverSocket = serverSocket; 
    } 

    @Override 
    public void run() { 
     try{ 
      System.out.println("Waiting for request..."); 
      Socket clientSocket = serverSocket.accept(); 
      System.out.println("Connection made."); 

      synchronized(block){ 
       System.out.print("Notifying server thread..."); 
       block.notify(); 
       System.out.println("...done"); 
      } 

      socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));    
      socketWriter = new PrintWriter(clientSocket.getOutputStream(), true); 

      String input; 
      while((input = socketReader.readLine()) != null){ 
       System.out.println(input); 
      } 
     }catch(IOException e){ 
      System.out.println("IOException!"); 
      e.printStackTrace(); 
     } 
    } 

} 

我遇到的問題是我不知道如何組合所有請求的行,以便我可以解析請求的文件。如果它只是不停地等待請求輸入,我將永遠無法解析整個請求。我怎麼解決這個問題?

+1

看看[的HttpCore(http://hc.apache.org/httpcomponents-core-ga/index.html)。它提供了與HTTP相關的組件,這將使構建服務器變得更加容易。 – eran

回答

2

您的while循環只會在客戶端和服務器之間的連接關閉後纔會中斷。由於客戶端在發送請求後正在等待相同的連接進行響應,連接將保持打開狀態,因此您的readline()將被阻止。在你的while循環中,你必須檢查每一行是否到達了請求數據的末尾。對於GET請求,您必須在HTTP標頭之後尋找空行。對於POST請求,您必須解析傳入的頭文件以尋找< Content-Length:N>。 THen處理剩餘的標題查找空白行(就像在GET情況下一樣)。一旦你找到空白,你必須閱讀< N>字節。此時,您知道您已完成處理請求數據,並且應該跳出讀取循環。

閱讀HTTP規範瞭解詳細信息。

1

第一行給出請求方法以及請求的路徑,以下行是請求標題,標題塊以空行結束。

這就是說,你是重新發明輪子:你可以使用com.sun.net.httpserver.HttpServer

相關問題