2011-07-31 46 views
1

在我創建的應用程序中,服務器接受來自客戶端的套接字連接並執行各種工作。客戶列表存儲在clients中,其類型爲LinkedList如何在代碼持有接受新插座時檢查某個變量?

,同時基於該clients隊列的大小與條件語句聲明我使用。

我想知道是否有解決以下的問題的方式......使服務器永遠不會掛起。

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 
    } 
} 

這樣,您將檢查客戶名單的每一秒左右的狀態。

不要忘記,如果您有其他線程訪問它來同步訪問clients。可以使用Collections.synchronizedList來包裝它,或者在訪問變量的代碼部分中進行適當的同步。

0

你的循環條件沒有任何意義,我。爲什麼只有在有現有客戶時纔有興趣接受新客戶?這個過程如何開始?

但一般設置在ServerSocket的超時會讓accept()方法拋出SocketTimeoutExceptions在這些間隔,所以你可以測試任何你需要測試。

+0

請檢查我的編輯 – user482594

+0

@ user482594您的編輯仍然不能解決我的問題。 – EJP

+0

它應該是「接受活着的客戶端之間的連接,而現有的活着客戶端」。但不存在'在有現有客戶的情況下接受新客戶' – user482594

0

我不確定我是否完全理解了您的問題,但假設以下幾件事情可能有效。首先假設你的客戶類有一個標誌存在它表明它是否還活着或死亡。

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

如果if(client.isAlive()){'通過,並且客戶端在該服務器被接受之前就死掉了,該怎麼辦? – user482594

+0

通常會有一個TimeoutException被配置爲處理這種情況。所以請檢查一下Cameron在說什麼。 –

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(); 
    } 
}