2011-12-01 64 views
3

我正在寫一個簡單的C#的TCP消息服務器,需要一個事實,即一個連接的客戶端一直沉默不語的最後TimeSpan timeout迴應。換句話說處理用戶超時在TCP服務器在C#

  1. 客戶端A連接。
  2. 客戶端A發送內容。
  3. 服務器響應客戶端A.
  4. 客戶端B連接。
  5. timeout時間過去沒有客戶端A發送任何東西。
  6. 服務器向A發送「ping」(不是在網絡ping中,而是如在消息中,)。
  7. 客戶端B發送內容。
  8. 服務器響應。
  9. pingTimeout ping發送到A後,連接到A被丟棄,客戶端被刪除。
  10. 如果B沉默太久,也會發生同樣的情況。

簡單的故事很短。如果timeout內的client[n]沒有聽到任何詞語,請發送ping。如果回答ping,則只需更新client[n].LastReceivedTime,但是,如果client[n]pingTimeout內未能響應,請刪除連接。

據我瞭解,這必須以某種調度的完成,使簡單地使一個循環說,這樣的事情

while(true) { 
    foreach(var c in clients) { 
     if(DateTime.Now.Subtract(c.LastReceivedTime) >= timeout && !c.WaitingPing) 
      c.SendPing(); 
     else if(DateTime.Now.Subtract(c.LastReceivedTime) >= timeout + pingTimeout && c.WaitingPing) 
      c.Drop(); 
    } 
} 

只會炒的CPU並會一點好處都沒有。是否有一個很好的簡單算法/類來處理這樣的情況,可以很容易地在C#中實現?它需要一次支持100-500個客戶端(至少,只有它能處理更多的情況纔是正面的)。如果使用專用線程,把一個Thread.Sleep(1000)在那裏,所以你不要像你說的炒CPU

回答

2

你的解決方案是好的,我想。 避免阻塞此線程上的呼叫例如,請確保您撥打SendPingDrop的呼叫是異步的,因此此線程只執行一件事。

另一解決方案是使用一個System.Timers.Timer每其具有等於你平計時器的間隔客戶端連接。我正在使用這種方法,並且已經用500個沒有問題的客戶端進行了測試。 (20秒間隔)。如果你的間隔時間更短,我不會推薦這個,並看看其他解決方案使用單線程來檢查(如你的解決方案)