PrintWriter を備えたシンプルな Java サーバー - ブラウザーへの応答送信の問題
-
09-10-2019 - |
質問
HTTPなどについて調べ始めたところです。URLConnection を使用して URL をサーバーに送信し、index.html ページを (プレーン テキストとして) プルダウンする単純な Java クライアントを作成しました。
今、私は単純なサーバーで作業していますが、最初のハードル (おそらく 2 番目か 3 番目) で立ち往生しており、サーバーをクライアントに適切に応答させることができません。
これはループ内の読み取りであり、FF や IE などからでも HTTP リクエストを正常に読み取ります。
while((message = in.readLine()) != null)
{
System.out.println(message);
out.write("something");
}
問題は、役立つものに応答させる方法がわからないことです。上記のコードで実行していることを実行させると、(HTTP リクエストには 6 行あるため) クライアントに「何か」を 6 回送信しますが、FF/IE などには何も送信しません。
また、私が追加したときもループを中断することはないようです System.out.println("test");
ループの後に出力する行がありますが、サーバーはその点に到達していないようです。readLine() は最初の HTTP リクエストの最後に null を返す必要がありますか?
私はサンとオラクルのウェブサイトの内容を読んできましたが、これがどのように機能するかについてはまだかなり行き詰まっています。
御時間ありがとうございます、
インフィニティフィズ
編集:おっと、コードをコピーするのを忘れていました。
サーバー.java:
package exercise2;
import java.net.*;
public class Server
{
public static void main(String[] args) throws Exception
{
boolean listening = true;
ServerSocket server = new ServerSocket(8081);
while(listening)
{
Socket client = server.accept();
new ServerThread(client).start();
}
server.close();
}
}
サーバースレッド.java:
package exercise2;
import java.io.*;
import java.net.*;
public class ServerThread extends Thread
{
private Socket socket = null;
public ServerThread(Socket s)
{
this.socket = s;
}
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String message, reply = "";
while((message = in.readLine()) != null)
{
System.out.println(message);
out.write("something");
}
System.out.println("test");
in.close();
out.close();
socket.close();
}
catch(IOException e)
{
System.err.println("error");
}
}
}
解決
まず、while ループ内の条件を次のように変更します。
while(in.hasNextLine()) {
message = in.nextLine();
//etc....
次に、サーバーの実行中に while ループを終了する必要がありません。if ステートメントを使用してリクエストを区別し、while ループ内でリクエストの解析をすべて実行する必要があります。while ループを終了するのは、接続を閉じる必要があるときだけです。それ以外の場合は、 nextLine()
このメソッドは何かを受信するまでブロックされます。
他のヒント
クライアントのコードを見ない限り、何が起こっているかについての私の最善の推測は次のとおりです。
クライアントがリクエストの書き込みを完了しているものの、接続を閉じていないため、サーバーはおそらく readLine() でブロックしていると考えられます (次のようになります)。クライアントは、同じ接続経由で応答を取得するまで待機する必要があります)。通常、HTTP サーバーはリクエストを読み取ったときにそれを解析します。に基づく これ, 、ヘッダーの終わりを区切るために「 」を探し、その時点で読み取りループを抜け出してリクエストを解析して応答します。