从this question尝试此代码。如果只是请求stackoverflow.com
,则会给出正确的回复,但当我尝试https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket
时,会返回HTTP/1.1 400 Bad Request
。是什么导致了这个问题?
以下是我从上述链接获得的工作代码,它提供了来自服务器的正确响应。
Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: stackoverflow.com");
pw.println("");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while ((t = br.readLine()) != null) {
System.out.println(t);
}
br.close();
试图将其更改为以下内容......
Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket");
pw.println("");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while ((t = br.readLine()) != null) {
System.out.println(t);
}
然后回复是HTTP/1.1 400 Bad Request
。
P.S。我不打算使用任何http库。
答案 0 :(得分:1)
问题出在您的请求中,这是不正确的。如果您使用
替换对PrintWriter的调用pw.println ("GET /questions/10673684/send-http-request-manually-via-socket HTTP/1.1");
pw.println ("Host: stackoverflow.com");
它应该有用。
修改强>
正如EJP在对此答案的评论中指出的那样,您应确保行结尾始终为\r\n
。你可以抛弃println-function而不是使用
pw.print ("Host: stackoverflow.com\r\n");
或you could change the default line ending to make sure println works correctly但是,这也可能影响程序的其他部分。
此外,您可以使用try-with-resources确保您的套接字在阅读完毕后关闭,这可以解决Steffen Ullrichs对您的问题的评论中的一个问题。
但是,在你的第一个例子中,你调用br.close();
,它应该关闭底层输入流,然后关闭套接字,这样也应该工作。但是,在我看来,最好明确地做到这一点。