2011-04-19 12 views
1

私はプロキシを書いて、次のコードを持っている:私をブロックすることなくサーバーの返信を読むにはどうすればよいですか?

Socket conUser; 
Socket conDest; 
try{ 
    ServerSocket ss = new ServerSocket(Integer.parseInt(p.getProperty("proxy.port"))); 
    while(true){ 
     //Connect to user 
     conUser = ss.accept(); 
     BufferedReader inputFromUser = new BufferedReader(new InputStreamReader(conUser.getInputStream())); 
     BufferedWriter outputToUser = new BufferedWriter(new OutputStreamWriter(conUser.getOutputStream(), "UTF8")); 

     //Get user request 
     StringBuffer req = new StringBuffer(); 
     getUserRequest(inputFromUser, req); 
     System.out.println("User requested the following:"); 
     System.out.println(req); 

     //Connect to server 
     InetAddress a = InetAddress.getByName(determineHost(req)); 
     conDest = new Socket(a,80); 

     //Send request to server 
     BufferedWriter outputToServer = new BufferedWriter(new OutputStreamWriter(conDest.getOutputStream(), "UTF8")); 
     InputStreamReader inputFromServer = new InputStreamReader(conDest.getInputStream(), "UTF8"); 
     outputToServer.write(req.toString()); 
     outputToServer.flush(); 

     System.out.println("=============================="); 
     System.out.println("Server replied with the following:"); 
     //Read reply from the server 
     //========================================= 
     int chars; 
       while ((chars = inputFromServer.read()) != -1) { 
        System.out.print((char)chars); 
        outputToUser.write(chars); 
        outputToUser.flush(); 
        //serverReply.append(chars); 
       } 
       //Relay reply to user 
      //outputToUser.write(serverReply.toString()); 
      //System.out.println(serverReply); 
      //outputToUser.flush(); 
     conUser.close(); 
     conDest.close(); 
    } 
} 
catch (Exception e) { 
     System.err.println(e); 
} 

何が起こることです:私は、接続を作成し、それが成功します。私もリクエストを送信し、それも成功します。また、返信を受け取り、ページのHTML全体を読み込むことができますが、読み込みがコンテンツの最後に到達したときに終了しないように見えるという点が異なります。

具体的には、私はGoogleのホームページを読み込もうとしていましたが、チャンク転送は0に達しています(これはチャンク転送の終了です)ので、読み込む入力がなくなったはずですが、読書を止める。私にとって奇妙なのは、プロキシのすべてのコード例がこのループを使用していることであり、動作すると仮定しても、コードと私の違いはほとんどありません。

ループを正しく終了させるにはどうすればよいですか?

EDIT:レコードのために、私は、TCP接続をさらに接続を処理するために開いたままにしておくべきであることを知っています。これは私が抱えている問題とは関係ありません。私は応答ごとにこのループを終了させる必要があります。

+0

私は、あなたが同じソケットで別の要求をしたいと考えていると思っています。あなたはこれをしたくないと言わなければならないか、十分なデータを持っているときに接続を切ってください(どれくらい期待するか) –

+0

!= -1の代わりに> 0を使うとどうなりますか?私はそれがread()で動作するかどうかはわかりませんが、後者の場合、特定の文字数、または残りのすべてを要求しているので、read(char []、int、int)利用可能なものが少なくなります。ゼロは、「ストリームの終わり」とまったく同じではないが、私のためにはうまくいくようであることを意味する。 – richj

答えて

1

一般的に、接続はそれぞれの応答の最後に閉じてではなく、です。 TCP接続の作成には比較的時間がかかります。そのため、接続は開いたままになっていますので、次のリクエストを送信する準備ができています。ここで

は説明のリンクのカップルです:

+0

はい私は永続的な接続とパイプラインについて知っていますが、これは私の質問に答えていません。私は応答ごとに終了する接続を取得したい。 – EpsilonVector

+0

接続を終了したい場合は、プログラムがHTTPプロトコルの詳細を理解しなければならないため、作業が複雑になります。私は2つの選択肢を見ることができます。 ** 1)**サーバーに渡すリクエストに「Connection:close」ヘッダーを追加します。 ** 2)**あなたが完全な応答(content-lengthバイトを読むか、それ以上chunkがないか)を読んだら、あなたの応答処理ループを中断してください。しかし、実際には完全なHTTPプロキシを作成していますが、これはソケット "echoer"よりはるかに複雑です。既存のライブラリを考慮するaxtavtのアドバイスは良いと思う。 –

1

あなたはHTTPレスポンスを受信した後、正常に接続を終了したい場合は、あなたの単純なループではありません十分な。 4.4メッセージ長RFC 2616で説明されているようにメッセージの終わりを判断し、接続を閉じる必要があります。

ただし、組み込みのURLConnectionなどの既存のライブラリを使用する方がよいでしょう。

関連する問題