Java HTTP/1.1获取请求BufferedReader readLine永不停止
你好,我正在制作一个HTTP客户端。我正在尝试获取google.com的html代码。我遇到了一个问题BufferedReader.readLine()函数被无限阻塞,因为远程服务器显然没有发送空行?还是我的要求错了 谢谢你的帮助Java HTTP/1.1获取请求BufferedReader readLine永不停止,java,sockets,http,inputstream,Java,Sockets,Http,Inputstream,你好,我正在制作一个HTTP客户端。我正在尝试获取google.com的html代码。我遇到了一个问题BufferedReader.readLine()函数被无限阻塞,因为远程服务器显然没有发送空行?还是我的要求错了 谢谢你的帮助 public static void main(String[] args) { String uri = "www.google.com"; int port = 80; Socket socket = new Soc
public static void main(String[] args) {
String uri = "www.google.com";
int port = 80;
Socket socket = new Socket(uri, port);
PrintWriter toServer = new PrintWriter(socket.getOutputStream(), true);
InputStream inputStream = socket.getInputStream();
get(uri, port, language, socket, toServer, inputStream);
}
public static void get(String uri, int port, String language, Socket socket, PrintWriter toServer, InputStream inputStream) {
try {
toServer.println("GET / HTTP/1.1");
toServer.println("Host: " + uri + ":" + port);
toServer.println();
// Parse header
StringBuilder stringBuilder = new StringBuilder();
BufferedReader fromServer = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = fromServer.readLine()) != null) {
stringBuilder.append(line);
}
System.out.println("done");
} catch (IOException e) {
e.printStackTrace();
}
}
您正在发送一个HTTP/1.1请求,该请求在默认情况下启用HTTP保持活动状态。这意味着服务器可能会在发送响应后保持TCP连接打开,以便接受来自客户端的更多请求。相反,您的代码假定服务器将在响应完成后通过显式地期望
readline
返回null
来关闭连接。但是,由于服务器不会关闭连接(或者只有在长时间超时后才会关闭连接),readline
将被阻塞
要解决此问题,请使用HTTP/1.0(默认情况下已关闭keep alive)而不是HTTP/1.1,或者通过添加连接:close
头显式告诉服务器不再发送请求
请注意,一般来说,HTTP比您刚才看到的几个示例所想的要复杂得多。你在问题中面临的问题只是你在继续这条道路时将面临的更多问题的一瞥。如果您真的想实现自己的HTTP处理而不是使用已建立的库,请研究实际的标准,而不仅仅是假设特定的行为。如果您正在创建HTTP客户端(为什么?),则需要阅读HTTP RFC,从RFC 2616开始。在这里,仅仅几行代码就已经出现了一些错误。但是不要继续这样做,Java已经有了一个内置的HTTP客户机,还有其他可用的。不要自己滚。太宽泛了。@user207421谢谢您的回复。我知道这很愚蠢,但这是我的计算机网络课程的作业。他还需要随请求发送一个内容长度,否则服务器甚至无法开始处理它。@user207421:鉴于这是一个get请求,正文的隐式长度为0,因此不需要
内容长度
标题。浏览器也不会在GET请求中发送这样的头。但您肯定会发现现有代码存在更多问题,例如使用错误的行分隔符(\n
而不是\r\n
)。感谢您的回复。关键是我不想关闭连接,因为我想在html中的图像路径上执行后续GET请求。这个想法是获取谷歌html及其图像,这样我就可以在本地完全查看该网站,而无需远程资源。(这是一项大学作业)。或者你会建议关闭连接,然后重新打开每个映像吗?@DirkxSenne:如果你想保持连接打开,你需要在代码中实现一个合适的HTTP解析器,这样你就可以确定响应实际何时结束,而不是假设readLine
神奇地理解HTTP。关闭连接使这更容易。同样,请研究实际标准,而不是仅仅假设。