複数のHTTPリクエストを一度に受け入れることができるマルチスレッドサーバーを作成しようとしています。Javaマルチスレッドサーバーが期待通りに機能しない
Serverコード:
package test.thread.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer implements Runnable {
private int serverPort = 8080;
private ServerSocket serverSocket;
private Thread runningThread;
private boolean isStopped;
public MyServer(int port){
this.serverPort = port;
}
@Override
public void run() {
synchronized (this) {
this.runningThread = Thread.currentThread();
}
openServerSocket();
while(!isStopped){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
//start a new thread for processing each request
new Thread(new RequestHandler(clientSocket)).start();
}
}
public synchronized void stop(){
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
private void openServerSocket(){
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
e.printStackTrace();
}
}
}
要求を処理するワーカー:
これは、入力ストリームからデータを読み取り、それを印刷します。その後、それは30秒間の睡眠になるはずです[CPUを必要としないいくつかの作業を表します]。スリープ時間後、サーバーはクライアントに応答します。
package test.thread.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
public class RequestHandler implements Runnable {
Socket clientSocket;
static int counter = 0;
public RequestHandler(Socket clientSocket){
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
InputStream input = this.clientSocket.getInputStream();
OutputStream output = this.clientSocket.getOutputStream();
DataInputStream inFromClient = new DataInputStream(input);
System.out.println(new Date()+": " +Thread.currentThread().getName() + " - Started : "+inFromClient.readUTF());
Thread.sleep(30000);
/*output.write(("HTTP/1.1 200 OK\n\n<html><body>" +
"Multi-threaded Server " +
"</body></html>").getBytes());*/
DataOutputStream outFromServer = new DataOutputStream(output);
outFromServer.writeUTF("Output");
outFromServer.flush();
output.close();
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
HTTPクライアント:
クライアントは、サーバーの睡眠時間については気にせず、5つの連続したリクエストを送信します。
package test.thread.server;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
public class MyClient {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
for(int i=0; i<5; i++){
Socket clientSocket = new Socket("localhost", 8080);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream inFromServer = new DataInputStream(clientSocket.getInputStream());
outToServer.writeUTF("Input");
outToServer.flush();
String output = inFromServer.readUTF();
System.out.println(new Date()+": "+output);
clientSocket.close();
}
}
}
ここで、1つのスレッドがスリープ状態になると、次のクライアント要求を処理することをサーバーが期待しています。しかし残念ながら、サーバーは前のリクエストが処理された後でなければ次のリクエストを受け付けません。
期待O/P:
Serverは 'スレッド-Xを - 開始:入力' を印刷する前に完了するために、現在の要求プロセスを待つべきではありません次の要求のために。
現在のO/P:
Server: Wed Feb 15 18:17:06 IST 2017: Thread-1 - Started : Input
Client: Wed Feb 15 18:17:36 IST 2017: Output
Server:Wed Feb 15 18:17:36 IST 2017: Thread-2 - Started : Input
Client:Wed Feb 15 18:18:06 IST 2017: Output
Server:Wed Feb 15 18:18:06 IST 2017: Thread-3 - Started : Input
Client:Wed Feb 15 18:18:36 IST 2017: Output
Server:Wed Feb 15 18:18:43 IST 2017: Thread-4 - Started : Input
Client:Wed Feb 15 18:19:13 IST 2017: Output
Server:Wed Feb 15 18:19:13 IST 2017: Thread-5 - Started : Input
Client:Wed Feb 15 18:19:43 IST 2017: Output
問題となることがありますか?
Haaaaa ....クライアントが犯人でした。私は自分のサーバーを疑って2時間以上かけてそれをデバッグしました。別のスレッドでクライアントリクエストを開始していたはずです!!! – Renjith