通过套接字手动发送 HTTP 请求

当我通过套接字发送正常的HTTP请求时,服务器不会以OK响应进行响应。我从Firefox复制了HTTP标头。代码如下:

Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.print("GET / HTTP/1.1");
pw.print("Host: stackoverflow.com");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while((t = br.readLine()) != null) System.out.println(t);
br.close();

但是,这是我收到的回复:

HTTP/1.0 408 Request Time-out
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>408 Request Time-out</h1>
Your browser didn't send a complete request in time.
</body></html>

我知道我可以使用 来执行此操作,但是为什么当我手动发送HTTP请求时,服务器无法识别它?URL.openStream()


答案 1

两件事:

  1. 您应该使用 而不是将条目打印到单独的行中。printlnprint
  2. HTTP 请求应以空行(链接)结尾。所以添加pw.println("");

答案 2

您不遵循 HTTP RFC

  • 标题行始终以 CR LF 结尾(即 加)。0x0d0x0a
  • 标头在第一个双换行符之后结束。在您的例子中,您不包括尾随换行符,因此服务器无法识别请求标头的末尾。

通常,您应该始终尝试使用现有的 HTTP 库。虽然HTTP似乎是一个简单的协议(与其他协议相比),但它具有相当严格的语法和语义规则。如果您尝试自己实现此功能,则应阅读并理解RFC 2616(以及相关)的相关部分。

可悲的是,已经有太多蹩脚的HTTP实现没有遵循标准,使每个人的生活都变得悲惨。省去麻烦,使用所选语言的HTTP库。


推荐