2011-04-19 43 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,除了讀取內容到達內容末尾時似乎不會終止。

具體來說,我試圖加載谷歌的主頁,並且分塊傳輸達到0(即 - 傳輸結束),因此應該沒有更多的輸入來讀取,但是這並沒有導致循環停止閱讀。對我來說也很奇怪的是,幾乎所有代理的代碼示例都使用這個循環,並假設它們工作正常,但我的代碼和我的代碼之間沒有太大的區別。

如何使循環正確終止?

編輯:備案,是 - 我知道,TCP連接應保持開放以處理更多的連接。這與我遇到的問題無關。我需要得到這個循環來終止每個響應。

+0

我相信,服務器認爲你可能想使同一插座上的其他請求。要麼你必須告訴它你不想這樣做,或者你有足夠的數據斷開連接(它會告訴你有多少期待) – 2011-04-19 10:07:10

+0

,如果你使用的是> 0,而不是會發生什麼!= -1?我不確定這是否適用於read(),但它應該與read(char [],int,int)一起工作,因爲在後一種情況下,您要求輸入特定數量的字符,或者其他所有字符更少可用。零意味着沒有更多 - 這不完全相同「流端」,但似乎對我更好。 – richj 2011-04-19 10:21:39

回答

1

通常的連接是不關閉在每個響應結束。創建TCP連接相對耗時,因此連接保持打開狀態,隨時可以發送下一個請求。

這裏有一些解釋性鏈接:

+0

是的,我知道持續連接和流水線,但這不能回答我的問題。我想要獲得連接來終止每個響應。 – EpsilonVector 2011-04-19 10:17:44

+0

如果您想要終止連接,事情會變得更加複雜,因爲您的程序必須瞭解更多的HTTP協議。我可以看到兩個選項。 ** 1)**將「Connection:close」標題添加到傳遞給服務器的請求中。 ** 2)**當您讀完完整的響應(讀取內容長度字節,或者沒有更多的塊)時,突破響應處理循環。然而,你確實正在寫一個完整的HTTP代理,這比套接字「echoer」複雜得多。 axtavt的建議,以考慮現有的圖書館聽起來不錯。 – 2011-04-19 10:50:39

1

如果你想接收HTTP響應後正確地終止連接時,您簡單的循環不足夠。您必須按照第4.4節「消息長度RFC 2616」中所述確定消息的結尾,然後關閉連接。

然而,這將是更好地使用現有的庫,如內置URLConnection

相關問題