私はサーバークライアントアプリケーションを設定しました。 (HOMEWORK)チャット:サーバー上のすべてのクライアントにメッセージを送信
これまでのところ、複数のクライアントをサーバーに接続し、クライアントが送信したメッセージをサーバーに集約させる方法と、クライアントのメッセージをクライアントに送り返して表示させる方法を考えましたチャットウィンドウに表示されます。
私の問題は、複数のクライアントにメッセージを送信しようとしています。 私はServerSocketとSocketライブラリのみを使用できます。
私は2つのクライアントがサーバーに接続していると言います。 1つのクライアントがメッセージを送信すると、そのメッセージはクライアントのチャットに表示されます。 2番目のクライアントはメッセージを送信し、1番目のクライアントはメッセージを受信せず、2番目のクライアントのチャットウィンドウに最初のクライアントのメッセージが表示されます。
本質的に、サーバーは、それぞれのクライアントがチャットボックスに表示していない最新のメッセージを送信しています。
サーバーからクライアントへの通信のためのコード:
Class CommunicationThread extends Thread {
//Vector containing all client sockets currently connected
//Held offsite, here for clarity
public Vector<Socket> socketVector;
public CommunicationThread (Socket clientSoc, Server ec3, Vector<Socket>socketVectorg)
{
//add new socket to vector, start thread
clientSocket = clientSoc;
socketVectorg.add(clientSocket);
this.socketVector = socketVectorg;
gui = ec3;
}
public void run()
{
System.out.println ("New Communication Thread Started");
try {
//Client's chat box (output)
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
true);
//Input line from client
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Server: " + inputLine);
gui.history.insert(inputLine + "\n", 0);
//*************HERE IS MY ISSUE*******************
for(Socket s : socketVector){
out = new PrintWriter(s.getOutputStream(),
true);
out.println(inputLine);
}
if (inputLine.equals("Bye."))
break;
if (inputLine.equals("End Server."))
gui.serverContinue = false;
}
out.close();
in.close();
clientSocket.close();
}
catch (IOException e)
{
System.err.println("Problem with Communication Server");
//System.exit(1);
}
}
}
私は、「アウト」を上書きしています知っているが、私がテストしていながら、それは私のコードであるので、私はそれは私の問題ではないと思います。
私の問題は上記のコードに記載されています。ベクトルは正確にソケットIDを格納しています。ベクターに基づいて新しいPrinterWriterを作成するので、私はそれがそれぞれのクライアントの出力フィールドを取得すると仮定しますが、そうではありません。
私の直感は、出力のスレッディングやクローズに問題があることですが、正直なところわかりません。
お勧めします。
ああ、主よ、コンストラクタのスレッドで 'start()'を呼ばないでください。オブジェクトはまだ完全に構築されていません。コンストラクタが返った後に 'start()'を呼び出します。この動作を強制する必要がある場合は、静的メソッド(ファクトリメソッド)を使用します。 – markspace
修正しました。ありがとうございました – mrybak3
問題の一部は、入力行ごとに新しい 'PrintWriter'を作成することかもしれません。それは "オフ"と思われる。また、私はこのクラスのGUIコードを参照してください。通常、GUIはサーバーではなくクライアント上で実行されます。だから私は上記のあなたのコードがサーバーコードであることを確認したい。正しい? – markspace