通过套接字手动发送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> 

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

两件事情:

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

你不遵循HTTP RFC 。

  • 标题行总是以CR LF结尾(即0x0d0x0a )。
  • 头在第一个双换行符后结束。 在你的情况,你不包括尾随的换行符,所以服务器不能识别请求头的结尾。

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

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

正确的解决scheme,它是真正的作品,它是跨平台:

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

正如前面的答案所述,下面的修复解决了这个问题。

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