3

空行を受信した後、BufferedReader (InputStream からの読み取り) がハングして読み取れない理由を理解しようとしています。

次のような POST リクエストを読み込もうとしています。

POST /test.php HTTP/1.0
Content-Length: 30
Content-Type: text/html;

postData=whatever&moreData...

投稿データが正しく (上記の形式で) 送信されていることはわかっていますが、投稿データを取得できません。次のコードが投稿データを出力し、さらに待機してハングすることを期待しています..しかし、実際に起こるのは、「Content-Type」行の後でハングすることです。

while (true) {
    System.out.println(bufferedReader.readLine());
}

ストリームを取得するために使用されるコード:

bufferedReader = new BufferedReader(clientSocket.getInputStream());

なぜこれが起こっているのか誰にも分かりますか?

ありがとう

4

1 に答える 1

4

このPOSTメソッドは、最後に改行文字を追加しません。あなたがする必要があるのは、を取得しContent-Length、最後の空の行の後にその数の文字を読み取ることです。

HTML次のページがあるとしましょう。

<html>
<head/>
<body>
    <form action="http://localhost:12345/test.php" method="POST">
        <input type="hidden" name="postData" value="whatever"/>
        <input type="hidden" name="postData2" value="whatever"/>
        <input type="submit" value="Go"/>
    </form>
</body>
</html>

ここで、コードに似た非常に単純なサーバーを起動します(このコードは全体でいっぱいですが、問題ではありません)。

public class Main {
    public static void main(final String[] args) throws Exception {
        final ServerSocket serverSocket = new ServerSocket(12345);
        final Socket clientSocket = serverSocket.accept();
        final InputStreamReader reader = new InputStreamReader(clientSocket.getInputStream());
        final BufferedReader bufferedReader = new BufferedReader(reader);
        int contentLength = -1;
        while (true) {
            final String line = bufferedReader.readLine();
            System.out.println(line);

            final String contentLengthStr = "Content-Length: ";
            if (line.startsWith(contentLengthStr)) {
                contentLength = Integer.parseInt(line.substring(contentLengthStr.length()));
            }

            if (line.length() == 0) {
                break;
            }
        }

        // We should actually use InputStream here, but let's assume bytes map
        // to characters
        final char[] content = new char[contentLength];
        bufferedReader.read(content);
        System.out.println(new String(content));
    }
}

お気に入りのブラウザにページを読み込んでボタンを押すと、コンソールGoに本文のコンテンツが表示されます。POST

于 2012-11-24T14:55:19.647 に答える