2011-12-01 46 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秒间隔)。如果你的间隔时间更短,我不会推荐这个,并看看其他解决方案使用单线程来检查(如你的解决方案)