Seprating Get请求响应主体在Java Socket编程

Seprating Get请求响应主体在Java Socket编程

问题描述:

我试图使用Java,仅使用的Java Socket编程(而不是的Apache HTTP客户端或任何其他API) 写这样程序的卷曲我想拥有的选项显示整个或唯一的响应正文,以便我向用户索取请求。目前,想出了下面的代码:Seprating Get请求响应主体在Java Socket编程

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     String t; 
     while ((t = br.readLine()) != null) { 
      if (t.isEmpty() && !parameters.isVerbose()) { 
       StringBuilder responseData = new StringBuilder(); 
       while ((t = br.readLine()) != null) { 
        responseData.append(t).append("\r\n"); 
       } 
       System.out.println(responseData.toString()); 
       parameters.verbose = false; 
       break; 
      } else if(parameters.isVerbose())// handle output 
       System.out.println(t); 
     } 
     br.close(); 

在详细选项上,它工作快速,显示了整个身体的反应,在不到一秒钟。但是当我想知道消息的正文时,需要花费很多时间(大约10秒)才能发布消息。 是否有人知道如何以更快的速度处理它? 谢谢。

+0

只是一个注释:代码的结构是很奇怪的,因为你消耗在内部循环的整个流,因此,外循环是在非详细情况没用。你也可以修改你的变量名('s'和't'不是明确的名字)。 – Dici

+0

难道是冗长的开关在你的代码中的另一个地方是活跃的?看起来你在一个案例中发送了一个像“Connection:close”这样的头文件,但在另一个案例中却没有。 – blafasel

+0

@blafasel我有完全相同的数据,只是一个布尔值差异试了一下。当我印刷整个东西时,它可以完美快速地工作。但是,只处理数据时,它变得非常慢! – Fezo

我会假设你慢的意思是,它几乎立即开始显示的东西,但不断的印刷线很长一段时间。写到控制台需要时间,你打印的每一行invidually而在其他的代码路径首先在内存中存储整个响应,然后将它刷新到控制台。

如果详细响应足够小以适应内存,则应该执行相同的操作,否则可以决定批量打印任意数量的行(即;您在内存中累积了n行,然后刷新到控制台,清除StringBuilder并重复)。

实施我的建议最优雅的方式是使用PrintStream包装BufferedOutputStream,本身包装System.out。我的所有评论和建议被浓缩在下面的代码片段:

private static final int BUFFER_SIZE = 4096; 

public static void printResponse(Socket socket, Parameters parameters) throws IOException { 
    try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     PrintStream printStream = new PrintStream(new BufferedOutputStream(System.out, BUFFER_SIZE))) { 

     // there is no functional difference in your code between the verbose and non-verbose code paths 
     // (they have the same output). That's a bug, but I'm not fixing it in my snippet as I don't know 
     // what you intended to do. 
     br.lines().forEach(line -> printStream.append(line).append("\r\n")); 
    } 
} 

如果使用任何语言结构,你不知道,随便问更多问题。

+0

谢谢你的回答。其实,没有什么开始显示几秒钟,然后所有的一起! 而详细和非冗长的输出是不同的。一个显示整个响应,另一个显示响应中收到的数据。 – Fezo

+0

因此让身体的方式是体与从响应其余部分的空行分隔。那部分是为了取出身体。 – Fezo

+0

@Fezo我没有看到你的代码有任何区别。在两种情况下都显示所有行(非第一种情况除外,但仅当它为空时没有太大区别)。 – Dici