6

以下のように、何かをテストするための小さなプログラムを作成しました。

public class Main {

    public static void main(String[] args){
        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        DataInputStream dataInputStream= null;

        BufferedWriter bufferedWriter = null;
        String line ;

        try {
            serverSocket = new ServerSocket(80);
            clientSocket = serverSocket.accept();

            dataInputStream = new DataInputStream(clientSocket.getInputStream());

            while((line = dataInputStream.readLine()) != null){
                System.out.println(line);
            }

            bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n Content-Length: 1354 \n <html>abcde<html/>");

            bufferedWriter.flush();

        } catch (IOException e) {
            System.out.println("socket port cannot be opened.");
            e.printStackTrace();
        } finally{
            try {
                serverSocket.close();
                bufferedWriter.close();
            } catch (IOException e) {
                System.out.println("socket port cannot be closed.");
                e.printStackTrace();
            }
        }


    }

}

インターネットからhttp応答形式を見つけました。正しいはずです。問題は、ブラウザが応答データ(回転するロゴから決定)を待ち続けることですが、データは正常に返されません。私が犯した間違いは何ですか?

ブラウザに「localhost」と入力してJavaプログラムに接続します。Javaプログラムで要求文字列を出力できますが、応答を返送できません。

4

3 に答える 3

3

それはContent-Lengthヘッダーフィールドでしょうか?応答を次のように置き換えてみてください。

bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n Content-Length: 18\n <html>abcde<html/>");

Content-Length: 18(対オリジナルに注意してくださいContent-Length: 1354

ブラウザは、アプリケーションがさらにデータを送信するのを待っていると思われます。

編集:これは私のために働きます:

import java.util.*;
import java.io.*;
import java.net.*;

public class Main {

    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        DataInputStream dataInputStream= null;

        BufferedWriter bufferedWriter = null;

        try {
            serverSocket = new ServerSocket(8080);
            clientSocket = serverSocket.accept();

            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            while (clientSocket.getInputStream().available() > 0) {
                String line = reader.readLine();

                if (line == null) {
                    break;
                }

                System.out.println(line);
            }

            bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n\n <html>abcde<html/>");
            bufferedWriter.flush();
            clientSocket.close();
        } catch (IOException e) {
            System.out.println("socket port cannot be opened.");
            e.printStackTrace();
        } finally{
            try {
                serverSocket.close();
                bufferedWriter.close();
            } catch (IOException e) {
                System.out.println("socket port cannot be closed.");
                e.printStackTrace();
            }
        }


    }

}

犯人はwhileループでした。より多くのデータをフェッチするために呼び出していたメソッドは、そのデータが使用可能になるまでブロックされていました(これは決して起こりません)。私がしたことが完全に必要かどうかはわかりませんが、機能します。

于 2012-08-03T17:16:33.697 に答える
3

まず最初に、送信されるHTTPメッセージにいくつかの問題があります。HTTPメッセージの各行は、単なる改行ではなく、CR LFによって区切られ/終了されます(これが問題になる可能性はないと思いますが、「」を置き換える必要があります。 \n"と"\r \ n ")。さらに、Content-Lengthはメッセージの本文の実際のサイズと等しくないため、置き換える必要があります。実際の本文の前に、すべてのHTTPメッセージに空の行が必要ですが、空の行はありません。最後に、次のように、のスラッシュ<html/>も前に来る必要がありますhtml</html>

総括する:

bufferedWriter.write("HTTP/1.0 200 OK\r\nDate: Fri, 31 Dec 1999 23:59:59 GMT\r\nContent-Type: text/html\r\nContent-Length:18\r\n\r\n<html>abcde</html>");

さて、本当の問題です。読み取りループは常により多くのデータを待っていました。readLine()の結果をnullと比較しても、実際には探していたものは実行されません。TCP接続はデータのストリームを作成し、クライアントが特定の瞬間にデータの送信を停止したかどうかはわかりません。代わりに、HTTPメッセージの先頭を示す空の行が見つかるまで読むことができます。Webブラウザーは通常、GETメッセージで追加のコンテンツを送信しないため、データが失われることはありません。

    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    while(!(line = reader.readLine()).isEmpty()){
        System.out.println(line);
    }
于 2012-08-03T17:20:07.340 に答える
1

2つの問題があります。

content-lengthヘッダーは、1354バイトが続くことを示しています。あなたは20かそこらを書いているだけです。コンテンツの長さはオプションです。正しい値を使用していない場合は、これを含めないでください。

ヘッダーの最後とコンテンツの前に空白行が必要です。".... Content-Length: xx\n\n<html>..."

于 2012-08-03T17:19:45.030 に答える