Java、套接字、BufferedReader 和 readline 挂起...... :(
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1577719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java, sockets, BufferedReader, and readline hang ... :(
提问by jettero
I'm not a Java programmer at all. I try to avoid it at all costs actually, but it is required that I use it for a class (in the school sense). The teacher requires that we use Socket(), BufferedReader(), PrintWriter() and various other things including BufferedReader()'s readLine() method.
我根本不是 Java 程序员。我实际上会不惜一切代价避免它,但我必须将它用于课堂(在学校意义上)。老师要求我们使用 Socket()、BufferedReader()、PrintWriter() 和其他各种东西,包括 BufferedReader() 的 readLine() 方法。
Basically, this is the problem I'm having. The documentation clearly states that readLine should return a null at the end of the input stream, but that's not what's happening.
基本上,这就是我遇到的问题。文档明确指出 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);
}
Instead of finishing at the end of the HTML, I get a blank line, a 0 and another blank line and then the next in.readLine() hangs forever. Why? Where's my null?
我没有在 HTML 的末尾完成,而是得到一个空行、一个 0 和另一个空行,然后下一个 in.readLine() 永远挂起。为什么?我的空在哪里?
I tried out.close() to see if maybe Yahoo! was doing a persistent http session or something (which I don't think it would without the header that we're willing to do it).
我尝试了 out.close() 以查看是否可能是 Yahoo! 正在做一个持久的 http 会话或其他东西(我认为如果没有我们愿意做的标头就不会这样做)。
All the Java sockets examples I'm finding on the net seem to indicate the while loop is the correct form. I just don't know enough Java to debug this.
我在网上找到的所有 Java 套接字示例似乎都表明 while 循环是正确的形式。我只是不知道足够的 Java 来调试这个。
回答by Bombe
Your problem is the content encoding “chunked”. This is used when the length of the content requested from the web server is not known at the time the response is started. It basically consists of the number of bytes being sent, followed by CRLF, followed by the bytes. The end of a response is signalled by the exact sequence you are seeing. The web server is now waiting for your next request (this is also called “request pipelining”).
您的问题是内容编码“分块”。当响应开始时不知道从 Web 服务器请求的内容的长度时,将使用此选项。它基本上由发送的字节数组成,然后是CRLF,然后是字节。响应的结束由您看到的确切序列表示。Web 服务器现在正在等待您的下一个请求(这也称为“请求流水线”)。
You have several possibilities:
你有几种可能:
- Use HTTP version 1.0. This will cause the webserver to automatically close the connection when a response has been sent completely.
- Specify the “Connection: close” header when sending your request. This will also close the connection.
- Parse content encoding “chunked” correctly and simply treat this as if the response is now complete—which it is.
- 使用 HTTP 版本 1.0。这将导致网络服务器在完全发送响应后自动关闭连接。
- 发送请求时指定“Connection: close”标头。这也将关闭连接。
- 正确解析“分块”的内容编码,并简单地将其视为响应现在已完成 - 确实如此。
回答by Jesper
So you're reading from a socket (you don't show that in your code, but that's what I gather from the text)?
所以你从一个套接字读取(你没有在你的代码中显示,但这是我从文本中收集的)?
As long as the other side is not closing the connection, Java doesn't know that it's at the end of the input, so readLine()is waiting for the other side to send more data and doesn't return null.
只要对方没有关闭连接,Java 就不会知道它在输入的末尾,因此readLine()正在等待对方发送更多数据并且不返回null。
回答by J?rn Horstmann
Your HTTP request is not complete without 2 carriage return + linefeed pairs. You should probably also call close after the request is sent:
如果没有 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();

