2011-04-19 61 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

相关问题