Java套接字收到HTTP/1.1400错误请求

Java套接字收到HTTP/1.1400错误请求,java,sockets,Java,Sockets,已从中尝试此代码。当只是请求stackoverflow.com时,它给出了正确的答复,但当我尝试https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket,它返回HTTP/1.1400错误请求。是什么导致了这个问题 下面是我从上面的链接获得的工作代码,它给出了服务器的正确响应 Socket s = new Socket(InetAddress.getByName("stackoverflow

已从中尝试此代码。当只是请求
stackoverflow.com
时,它给出了正确的答复,但当我尝试
https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket
,它返回
HTTP/1.1400错误请求
。是什么导致了这个问题

下面是我从上面的链接获得的工作代码,它给出了服务器的正确响应

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.1400坏请求


另外,我不打算使用任何http库。

问题在于您的请求,这是不正确的。如果将对PrintWriter的调用替换为

pw.println ("GET /questions/10673684/send-http-request-manually-via-socket HTTP/1.1");
pw.println ("Host: stackoverflow.com");
它应该会起作用


编辑: 正如EJP在对此答案的评论中指出的那样,您应该确保行尾始终是
\r\n
。您可以放弃println函数,改为使用

pw.print ("Host: stackoverflow.com\r\n");
但是,这也可能影响程序的其他部分


此外,您还可以尝试使用资源来确保在读完本文后关闭套接字,这解决了Steffen Ullrich在对您的问题的评论中提出的一个问题


但是,在第一个示例中,您调用
br.close(),它应该关闭底层输入流,而底层输入流又关闭套接字,这样也应该可以工作。但是,在我看来,最好明确地这样做。

主机应该保持工作代码中的状态,但是您必须将主机上方的行更改为
GET/questions/10673684/通过套接字http/1.1手动发送http请求。
@Alex您应该将该注释作为答案放置在answerHi@Alex中。你是对的。非常感谢你。如果您要放置一个答案,我会标记它。另外,您应该使用
\r\n
作为行结束,而不是
\n
,并且您不应该期望服务器在响应后关闭连接,因为您已经使用HTTP版本1.1隐式请求了持久连接。出于同样的原因,您还需要能够处理数据的分块传输编码。建议在实现协议时查看适当的标准,而不仅仅是猜测行为。除非您至少修复了线路终止,否则不能这样做,这是一个不使用
println()
的问题。您可能会幸运地拥有一系列宽容的HTTP服务器,但任何HTTP服务器都有权仅基于此忽略/拒绝请求。我试图在我的编辑中解决您的问题。如果愿意,您仍然可以使用
println()
,您只需在创建PrintWriter实例之前设置line.separator属性即可。如果我没有亲眼看到Apache发出的400个错误请求,我不会相信位于的SSLSocketClient.java示例代码也缺少您的洞察。Sun/Oracle仅在Windows上测试?强大的力量是如何倒下的!