私はWindowsXPのEclipseでJavaをプログラミングしています。ProcessBuilderを使用してサーバーと2つのクライアントを実行するマルチプロセスシミュレーションがあります。サーバーはスレッドを開始して、クライアントごとに1つずつ、2つの異なるソケットをリッスンします。各クライアントのコードをコメントアウトして、他のクライアントを完全に正常に動作させることができます。両方を実行しようとすると、1つのクライアントが常にConnectExceptionでエラーになります:接続が拒否されました:接続します。どちらが遅いかはわかりませんが、どちらのクライアントであるかはわかりません。サーバーを起動した後、クライアントの前で一時停止できます。netstatは、両方のソケットがアクティブであることを確認します。これを引き起こしている可能性がありますか?以下にいくつかの簡略化されたコードがあります。
更新:コメントに基づいて、単一のソケットでサーバーをマルチスレッド化するようにコードを編集しましたが、それでも同じ問題が発生します。以下のコードは変更を反映しています。他のクライアントがソケットを開く前に、一方のクライアントがソケットを開いたり閉じたりしているようです。各クライアントの最後に一時停止ステートメントをスローして、他のクライアントを終了させることができますが、これは修正であり、解決策ではありません。では、本当の問題は、閉じるように指示するまでServerSocketをリッスンし続けるにはどうすればよいかということです。
サーバ
try{
server = new ServerSocket(sockNum);
} catch (IOException e) {
System.out.printf("Could not listen on port %d\n",sockNum);
System.exit(-1);
}
while(true){
ClientWorker w;
try{
Socket connection = server.accept();
w = new ClientWorker(connection);
Thread t = new Thread(w);
t.start();
} catch (IOException e) {
System.out.printf("Accept failed: %d\n",sockNum);
System.exit(-1);
}
}
class ClientWorker implements Runnable {
private Socket client;
ClientWorker(Socket client) {
this.client = client;
}
public void run(){
Object line;
ObjectInputStream in = null;
PrintWriter out = null;
try{
in = new ObjectInputStream(client.getInputStream());
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while(true){
try{
line = in.readObject();
//Send data back to client
out.println("Sent from broker");
if(line instanceof String)
System.out.println(line);
else
System.out.println(line.getClass());
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
クライアント
try{
socket = new Socket("localhost", socketNum);
out = new ObjectOutputStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.writeObject(message);
String line = in.readLine();
System.out.println(line);
} catch (UnknownHostException e) {
System.out.println("Unknown host: localhost.eng");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
コントローラ
ProcessBuilder server = new ProcessBuilder("java.exe","-Xss64m","-cp","bin;jscheme.jar","ServerProcess");
server.redirectErrorStream(true);
Process runServer = server.start();
ProcessBuilder clientA = new ProcessBuilder("java.exe","-Xss64m","-cp","bin;jscheme.jar","ClientAProcess");
clientA.redirectErrorStream(true);
Process runClientA = clientA.start();
ProcessBuilder clientB = new ProcessBuilder("java.exe","-Xss64m","-cp","bin;jscheme.jar","ClientBProcess");
clientB.redirectErrorStream(true);
Process runClientB = clientB.start();