52

ソケット経由で通常の 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 要求を識別しないのはなぜですか?

4

4 に答える 4

48

2つのこと:

  1. エントリを別の行に出力するprintln代わりに使用する必要があります。print
  2. HTTP リクエストは空白行 ( link ) で終了する必要があります。だから追加pw.println("");
于 2012-05-20T13:13:31.627 に答える
22

HTTP RFCに従っていません。

  • ヘッダー行は常に CR LF (つまり0x0dplus 0x0a) で終了します。
  • ヘッダーは、最初の二重改行の後に終了します。あなたの場合、末尾の改行を含めないので、サーバーはリクエストヘッダーの終わりを認識しません。

通常、常に既存の HTTP ライブラリを使用するようにしてください。HTTP は単純なプロトコルのように見えますが (他のプロトコルと比較しても)、かなり厳密な構文規則と意味規則があります。これを自分で実装しようとする場合は、RFC 2616 の関連部分 (および関連部分) を読んで理解する必要があります。

悲しいことに、標準に準拠していない粗悪な HTTP 実装がすでに多すぎて、誰もが惨めな生活を送っています。手間を省き、選択した言語の HTTP ライブラリを使用してください。

于 2012-05-20T13:18:42.810 に答える
12

実際に機能し、クロスプラットフォームである正しい修正:

    pw.print("GET / HTTP/1.1\r\n");
    pw.print("Host: stackoverflow.com\r\n\r\n");
于 2015-04-05T12:24:59.927 に答える