2016-08-31 11 views
-1

私はサーバーマルチクライアント通信アプリケーションを作成しています。クライアントをループして受け入れるThreadを作成する必要があります。私の現在のコードは次のとおりです。ただしJava while(真)ループが1回実行されます

Thread acceptor = new Thread() { 
    public void run() { 
     while(true){ 
      System.out.println("looking for clients"); 
      try{ 
       Socket s = serverSocket.accept(); 
        clientList.add(new ConnectionToClient(s)); 
       } 
       catch(IOException e){ e.printStackTrace(); } 
      } 
     } 
    } 
}; 
acceptor.setDaemon(true); 
acceptor.start(); 

、私は自分のアプリケーションを実行すると、テキストlooking for clientsは一度だけ表示され、一切のクライアントが接続できません。

なぜ私のwhile(true)ループは実際にはループしておらず、一度だけ動作しているのか分かりません。

EDIT:

ConnectionToClientコンストラクタは次のとおりです。

ConnectionToClient(Socket socket) throws IOException { 
    this.socket = socket; 
    in = new ObjectInputStream(socket.getInputStream()); 
    out = new ObjectOutputStream(socket.getOutputStream()); 

    Thread read = new Thread(){ 
     public void run(){ 
      while(true){ 
       try { 
        Object obj = in.readObject(); 
        messages.put(obj); 
       } catch(IOException | ClassNotFoundException | InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 
    read.start(); 
} 
+2

「acceptor.setDaemon(true);」とは何と思いますか?実際に何人のクライアントが接続しようとしていますか? –

+0

私が望むだけ多くのクライアントをサポートしようとしていますが、私は1〜3人のクライアントでそれをテストしています。 –

+0

'accept'のためのjavadoc - '接続が確立されるまでメソッドがブロックされる ' –

答えて

0

@ErwinBolwidtに感謝します。

問題があった:

1).setDaemon(true)が問題を引き起こしていました。

2)クライアントが接続される前にを作成すると、サーバーに送信する必要があるヘッダーが読み取られ、クライアントからサーバーに送信されなくなりました。これを読み取りスレッドに移すことで、クライアントは実際にサーバーに接続することができました。

もう一度@ErwinBolwidtに感謝します。

4

あなたはacceptor.setDaemon(true);を呼んでいます。

Its Javadocは説明する:

マークを、このスレッドをデーモンスレッド またはユーザスレッドのいずれかと。実行中のスレッドがすべて のデーモンスレッドだけである場合、Java仮想マシンは終了します。

したがって、実行中のスレッドのみをデーモンスレッドとしてマークします(mainメソッドの終了時にメインスレッドが終了するため)。ループが1回繰り返されていることは幸いです。デーモン以外のスレッドがなくなると、すぐにVMが終了するためです。

ソリューション:acceptor.setDaemon(true);


あなたの更新のポストを読み込む行を削除し、他の問題を示し、コンストラクタConnectionToClient(Socket socket)が誤って、クライアントがデータを送信するまでブロックアクセプタスレッドSocketから読み取ろうとします。

問題は、ObjectInputStreamのコンストラクタがオブジェクトストリームのヘッダを読み取ろうとしていることです。

したがって、とObjectOutputStreamの構成をreadスレッドに移動して、acceptorスレッドをブロックしないようにする必要があります。

+0

'acceptor.setDaemon(true);のすべての痕跡を削除しましたが、それはまだ1回だけ実行されます。 –

+0

@ C.Coleおそらくあなたはまだクラスファイルを再構築していないでしょうか? –

+0

また、私のVMは終了しません。それはちょうど 'のための'のクライアントを探して待っています。 –

関連する問題