2009-10-16 56 views
5

我根本不是一个Java程序员,我尽量避免它,但它需要我在课堂上使用它(在),老师要求我们使用Socket(),BufferedReader(),PrintWriter()和其他各种东西,包括BufferedReader()的readLine()方法。有该文件中明确指出的readLine应在输入流的末尾返回空值,但是这不是发生了什么。Java,套接字,BufferedReader和readline挂起... :(

Socket link  = new Socket(this.address, 80); 
BufferedReader in = new BufferedReader(new InputStreamReader(link.getInputStream())); 
PrintWriter out = new PrintWriter( new PrintWriter(  link.getOutputStream(), true)); 

out.print("GET blah blah blah"); // http request by hand 
out.flush(); // send the get please 

while((s=in.readLine()) != null) { 

    // prints the html correctly, hooray!! 
    System.out.println(s); 
} 

而是在HTML结束整理,我得到了一个空白升ine,0和 另一个空行,然后下一个in.readLine()永远挂起。为什么? 我的null在哪里?

我试了out.close()看看也许雅虎!正在做一个持续的http 会议或其他事情(我不认为它会没有 我们愿意这样做)。

我在网上找到的所有Java套接字示例似乎表示 while循环是正确的形式。我只是不知道足够的Java来调试 这个。

回答

8

你的问题是内容编码“chunked”。当响应开始时,从Web服务器请求的内容的长度未知时,将使用此参数。它基本上由正在发送的字节数组成,后面跟着CRLF,后面跟着字节。响应的结束通过您所看到的确切顺序发出信号。 Web服务器现在正在等待下一个请求(这也称为“请求流水线”)。

您有几种可能性:

  • 使用HTTP 1.0版。这将导致Web服务器在响应完全发送时自动关闭连接。
  • 发送请求时指定“Connection:close”标题。这也将关闭连接。
  • 正确解析内容编码“chunked”,并简单地对待它,就好像响应现在完成 - 它是。
+0

这是有道理的。我需要检查标题。 我只是要使用http1.0。 – jettero

+0

是的,对于一个学校练习来说,这是最明智的选择。 – Bombe

7

所以你从一个套接字读取(你没有在你的代码中显示,但这是我从文本中收集的)?

只要对方没有关闭连接,Java就不知道它在输入的末尾,因此readLine()正在等待另一端发送更多数据,并且不返回null

+0

...从套接字读取,是的。我在这个问题上补充说,谢谢。 – jettero

4

尝试GET url HTTP/1.0HTTP/1.0告诉服务器,每个连接不能处理多个文档。在这种情况下,服务器应在发送结果后关闭连接。

+0

是的,这是有道理的,它的工作原理。在其他语言中,我只需关闭套接字的一侧,以便Web服务器知道只有一个请求...但是当我out.close()时,它似乎关闭了链接的两侧。 有一种方法可以准确地关闭一边吗?我误解了会发生什么? – jettero

+0

你说得对,关闭''out''也会关闭传入的流。 IIRC,这是Java URL处理程序类中的缺陷/功能。 –

0

如果没有2回车+换行对,您的HTTP请求不完整。您也应该在请求发送后致电close:

out.print("GET /index.html HTTP/1.0\r\n"); 
// maybe print optional headers here 
// empty line 
out.print("\r\n"); 
out.flush(); 
out.close();