【问题标题】:Send HTTP request manually via socket通过套接字手动发送 HTTP 请求
【发布时间】:2012-05-27 06:29:56
【问题描述】:

当我通过套接字发送正常的 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>

我知道使用URL.openStream()可以做到这一点,但是为什么我手动发送HTTP请求时服务器无法识别?

【问题讨论】:

  • 我认为您必须在所有标题之后发送一个额外的换行符; pw.println();,并使用println() 作为标题?
  • @Torious 是的,这就是问题所在。谢谢:)
  • 对于 HTTP,换行符的格式必须为 \r\n。
  • 好吧,当我尝试你的代码时它不会打印任何东西。

标签: java http sockets network-programming http-headers


【解决方案1】:

真正有效且跨平台的正确修复:

    pw.print("GET / HTTP/1.1\r\n");
    pw.print("Host: stackoverflow.com\r\n\r\n");

【讨论】:

  • 我使用 Host : 而不是 Host: 并且都收到错误请求 (400) 并且花了一天时间才意识到,这真的很糟糕。
【解决方案2】:

如前面的答案所述,以下修复解决了问题;

pw.print("GET / HTTP/1.1\n\r\n");
pw.print("Host: stackoverflow.com\n\r\n");

【讨论】:

    【解决方案3】:

    两件事:

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

    【讨论】:

    • 完美。添加空行很重要!
    • 这仅适用于 Windows 机器。在 linux 上,它只会打印 LF 而不是 HTTP 规范所需的 CRLF。查看其他答案。
    • 当我把主机改成pw.println("Host: httpstackoverflow.com/questions/10673684/send-http-request-manually-via-socket");时为什么给和HTTP/1.1 400 Bad Request
    【解决方案4】:

    你没有关注HTTP RFC

    • 标题行总是以 CR LF 结尾(即0x0d 加上0x0a)。
    • 标头在第一个双换行符之后结束。在您的情况下,您不包含尾随换行符,因此服务器无法识别请求标头的结尾。

    通常,您应该始终尝试使用现有的 HTTP 库。尽管 HTTP 看起来是一个简单的协议(并且与其他协议相比),但它具有相当严格的句法和语义规则。如果您尝试自己实现这一点,您应该已经阅读并理解了 RFC 2616(和相关)的相关部分。

    可悲的是,已经有太多糟糕的 HTTP 实现不遵循标准,这让每个人的生活都很痛苦。省去麻烦,使用您选择的语言的 HTTP 库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 2014-10-26
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      相关资源
      最近更新 更多