2011-10-19 5 views
1

私は、ブラウザから要求を読み込み、リクエストから要求されたファイルを解析してから、適切なHTMLをブラウザに返す単純なHTMLサーバーを作ろうとしています。私は複数のリクエストを処理できる必要があるので、私は現在、別の実行可能クラスのRequestHandlerの親として動作するServerクラスを持っています。サーバー上で接続が確立されるたびに、実行可能クラス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

を使用することができます。これはHTTP関連のコンポーネントを提供します。これにより、サーバーの構築がはるかに容易になります。 – eran

答えて

2

あなたのwhileループは、クライアントとサーバーの間の接続が切断された後にのみ切断されます。要求を送信した後、クライアントは同じ接続で応答を待機しているため、接続は開いたままであるため、readline()はブロックされます。あなたのwhileループでは、リクエストデータの最後に達したかどうかをすべての行の後でチェックする必要があります。 GETリクエストの場合、HTTPヘッダーに続く空白行を検索する必要があります。 POST要求の場合は、受信ヘッダを解析して、< Content-Length:N>を検索する必要があります。残りのヘッダーは空行を探します(GETの場合と同様)。空白のようなものを見つけたら、< N>バイトを読まなければなりません。この時点で、要求データの処理が完了しており、読み取りループから抜け出すはずです。

詳細については、HTTP仕様をお読みください。

1

最初の行には要求メソッドと要求されたパスがあり、次の行は要求ヘッダーで、ヘッダーブロックは空白行で終わります。

前記、あなたは車輪の再発明している:あなたは[HttpCore](http://hc.apache.org/httpcomponents-core-ga/index.html)を見てみましょうcom.sun.net.httpserver.HttpServer

関連する問題