2013-02-13 42 views
0

我目前正在實施一個web代理,但我遇到了一個問題。我可以從瀏覽器解析我的請求,並提出一個新的請求相當好,但我似乎有與response.It問題一直掛我的反應循環我的回覆似乎在響應類中掛起,而與套接字工作

serveroutput.write(request.getFullRequest()); 
      // serveroutput.newLine(); 
       serveroutput.flush(); 
       //serveroutput. 
       //serveroutput.close(); 
      } catch (IOException e) { 
       System.out.println("Writting tothe server was unsuccesful"); 
       e.printStackTrace(); 
      } 
      System.out.println("Write was succesful..."); 
      System.out.println("flushed."); 

      try { 
       System.out.println("Getting a response..."); 
       response= new HttpResponse(serversocket.getInputStream()); 
     } catch (IOException e) { 
       System.out.println("tried to read response from server but failed"); 
       e.printStackTrace(); 
      } 

       System.out.println("Response was succesfull"); 



     //response code 

     public HttpResponse(InputStream input) { 
    busy=true; 

     reader = new BufferedReader(new InputStreamReader(input)); 
     try { 
      while (!reader.ready());//wait for initialization. 

      String line; 
      while ((line = reader.readLine()) != null) { 
       fullResponse += "\r\n" + line; 


      } 

      reader.close(); 
      fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n"; 
     } catch (IOException`` e) { 

      e.printStackTrace(); 
     } 
     busy = false; 
    } 
+0

服務器在響應結束時是否發送「新行」? 'reader.readLine()'...從Java文檔*「一行被認爲是由換行符('\ n'),回車符('\ r')或一個小車返回,然後立即換行「*另外 - 您可能不需要'reader.ready()',因爲'reader.readLine()'將會阻塞,直到它從緩衝區以任何方式讀取一行爲止......恕我直言 – MadProgrammer 2013-02-13 00:38:30

+0

我真的不能告訴瀏覽器發送什麼,直到我解析整個迴應 – user1850254 2013-02-13 00:42:06

回答

1
while (!reader.ready()); 

這條線進入一個無限循環中,顛簸的CPU,直到流是可用於讀取。一般不是一個好主意。

+0

我的問題實際上是在讀線部分。它似乎掛在那裏。 – user1850254 2013-02-13 00:41:25

+0

@ user1850254儘管如此,你應該刪除這條毫無意義的路線。 – EJP 2013-02-13 02:30:36

2

您正在對套接字進行阻塞,同步讀取。在發送頁面之後,Web服務器不會關閉它們的連接(如果指定了HTTP/1.1),所以它將坐在那裏並阻塞,直到Web服務器超時連接。要做到這一點,你需要尋找Content-Length標題,並在數據到達正文時讀取適當數量的數據。

你真的不應該試圖重新發明輪子,而是使用提供的核心Java HttpURLConnection或Appache HttpClient來提出請求。

+0

我只是設計一個代理,並想了解套接字編程的細節。 – user1850254 2013-02-13 00:40:44

+0

那麼,你去:)你將不得不正確處理HTTP協議,如果是這樣的話......或將因爲我上面陳述的原因而掛起。 – 2013-02-13 00:44:29

+0

您可以請我指出一個方向或給我幾個步驟來跟隨。 – user1850254 2013-02-13 00:50:57

1

你在這裏犯了很多錯誤。

  • 使用旋轉循環調用ready()而不是僅僅在隨後的讀取中阻塞。如果您不知道數據是文本,則使用Reader
  • 即使稍微沒有實施HTTP 1.1協議。

而不是審查您的代碼,我建議您檢查HTTP 1.1 RFC。您需要爲HTTP 1.1實現簡單代理所需的操作如下:

  1. 從客戶端讀取一行。這應該是一個CONNECT命令,命名您要連接的主機。用DataInputStream而不是BufferedReader讀取它,並且我知道它已被棄用。

  2. 連接到目標。如果成功,請將HTTP 200發送回客戶端。如果沒有,發送適當的HTTP狀態並關閉客戶端。

  3. 如果您在(2)處成功,則啓動兩個線程,一個將所有數據從客戶端複製到目標,作爲字節,另一個做相反的處理。

  4. 當您獲得EOS閱讀其中一個襪子時,請在另一個襪子上撥打shutdownOutput()

  5. 如果shutdownOutput()尚未在此線程的輸入套接字上調用,則退出該線程。

  6. 如果它已被調用,關閉兩個套接字並退出線程。

請注意,您要解析除CONNECT命令任何東西;你不必擔心內容長度;你只需要傳輸字節,然後正確地傳輸EOS。

+0

如果我可能會問你一個簡單的問題。當你不知道數據是否是文本時,使用閱讀器是什麼意思 – user1850254 2013-02-13 23:44:39

+0

我的意思是*除非你知道數據是文本,否則不要使用「閱讀器」。 HTTP請求的主體可以是任何東西。使用'InputStream.' – EJP 2013-02-14 00:03:51