2011-07-31 6 views
1

私が作ったアプリケーションでは、サーバーはクライアントからのソケット接続を受け入れ、さまざまな作業を行います。クライアントのリストは、LinkedListタイプのclientsに格納されています。新しいソケットを受け入れるコードが保持されている間、変数を確認するにはどうすればよいですか?

私は、clientsキューのサイズに基づく条件文を使ってwhile文を使用しています。

以下に説明する問題を解決する方法があるかどうかを知りたいので、サーバーが永遠にハングしないようにします。

while(clients.size()>0){ //few clients the queue is alive at the moment 
    //Suddenly, all clients in the queue shut down at this point in the while loop, 
    //Another thread, which checks clients knows that clients are dead 
    //so clients.size() becomes 0, but there is no way to check that at this point 
    //and server is expecting for connection clients forever 

    Socket socket= server.accept(); 
    socket.close(); 
} 
//printout results 

編集

クライアントリストだけで既存のクライアントではありません。これは生きているクライアントのリストです。このリストは別のスレッドによって更新されます。

私は上記のステートメントを持っています。生き残ったクライアントが残っていない状態で仕事をしたいからです。 (仕事が終了したばかりか、死亡したばかりか)

タイムアウト例外を使わずにこの問題を解決したいのは、クライアントがランダムに応答するからです。 (もう一度、ハートビート技術を使って別のスレッドでクライアントの活性をチェックします)

+0

なぜタイムアウトを使用しないソリューションが欲しいですか? 'SocketTimeoutException'を使うことは何も問題ありません。あなたはループの中でそれを捕まえ、それを適切に扱うことができます(私の答えは例を見てください)。また、必要に応じて、異なるソケットに対して異なるタイムアウトを設定することもできます。 –

+0

クライアントはサーバに応答しなければなりません。これは、クライアントに与えられた引数に基づいて1秒か1分かかります。そのため、私はクライアントを待ち行列に入れて管理しています。このリストは別のスレッドによって更新されます。 – user482594

+0

はい、ループ内の次の接続*を待っているタイムアウトを持つことができます。タイムアウトは、あなたが次のクライアントをあきらめることを意味するものではありません。あなたがまだ待つべきかどうかを確認する機会を与えます。無期限に待つことは、ほとんど常に悪い考えです。クライアントがクラッシュしたり、応答する前に停電が発生した場合はどうなりますか?ネットワークに問題がある場合はどうなりますか?堅牢なシステムを作成している場合は、これらのケースを処理できるように**必要です**。基本的に、あなたが*タイムアウトしていなければ、 'socket.accept'への呼び出しは永遠に待機します。これは本当にあなたが望むものですか? –

答えて

2

あなたはServerSocketにタイムアウトを設定し、SocketTimeoutExceptionキャッチすることができます:

server.setSoTimeout(1000); 
while (clients.size() > 0) { 
    try { 
     server.accept(); 
    } 
    catch (SocketTimeoutException e) { 
     // Ignore 
    } 
} 

2番目かそこらのすべてのクライアントリストのステータスをチェックします。この道を。

他のスレッドがアクセスしている場合は、clientsへのアクセスを忘れないようにしてください。 Collections.synchronizedListを使用してラップするか、変数にアクセスするコードの部分に適切な同期を設定します。

0

ループ状態はわかりません。既存のクライアントがある場合に新しいクライアントを受け入れることに興味があるのはなぜですか?このプロセスはどのように開始されますか?

一般的に、ServerSocketのタイムアウトを設定すると、accept()メソッドはSocketTimeoutExceptionsをそれらの間隔でスローし、テストする必要があるものをテストできます。

+0

質問の編集内容を確認してください – user482594

+0

@ user482594あなたの編集内容はまだ私の質問に対処していません。 – EJP

+0

「既存の生きているクライアントがある間に、生きているクライアント間の接続を受け入れる」べきである。既存のクライアントが存在する場合に新しいクライアントを受け入れることはできません。 – user482594

0

私はあなたの質問を完全に理解しているとは確信していませんが、いくつかのことを前提にすると以下のように動作するかもしれません。最初に想定しているのは、クライアントクラスにフラグaliveが存在するかどうかを示すものです。

while(clients.size()>0){ 
    client = clients.remove(); 
    if (client.isAlive()) { 
     Socket socket= server.accept(); 
     socket.close(); 
    } 
} 
+0

'if(client.isAlive()){'が実行され、クライアントがその直後に、そしてサーバーによって受け入れられる前に、どうすればいいですか? – user482594

+0

通常、このような状況を処理するためにTimeoutExceptionが構成されています。だからキャメロンが言っていることをチェックアウトする。 –

0

既知の点でクライアントのサイズが変更されるように、クライアントの同期が必要なように見えます。

0

すべてのクライアントがなくなったときに、serversocketを停止する余分なスレッドはどうですか? :)何かのように

new Thread() { 
    public void run() { 
     if (clients.isEmpty()) { 
      try { server.close();} catch (IOException e){...} 
     } 
    } 
}.start(); 

while(clients.size()>0){ 
    if (!clients.isEmpty()) { 
     Socket socket= server.accept(); 
     socket.close(); 
    } 
} 
関連する問題