有效且高效地管理许多TCP连接

时间:2010-12-22 21:11:21

标签: c# .net c#-4.0 tcp

我很好奇是否有人可以就如何有效管理大量TCP连接给我任何想法或建议。我正在谈论1000个TCP连接(可能更多)。管理所有这些连接的应用程序需要定期从客户端(连接的另一端)提取信息。例如,可能每30秒。我会使用.NET 4.0。有什么内置的东西来帮助这个或一个特殊的方法来构建所有这些连接来管理所有这些连接而不会让这个应用程序陷入困境,它没有用吗?

6 个答案:

答案 0 :(得分:7)

我可以给你一点见解:

甚至不考虑每个连接产生一个线程。使用框架的内置异步/任务框架来管理连接。那是;让线程池执行它。

另外,要小心仔细观察你的线程在做什么;确保您不能一次从多个线程读取/写入连接的流。但同时,要小心你如何使用锁定机制这样做,这样你就不会得到一个具有1000个活动连接的进程,以及一个充满线程的线程池等待获取它们永远不会获得的锁。

答案 1 :(得分:3)

只要您只使用异步API,处理数千个连接并不困难。 “每个连接一个线程”的概念不仅不能扩展,而且(在一般协议的情况下)是错误的。请注意,异步API与使用ThreadPool不同。

异步编程需要花费一些时间来实现,但实际上并不复杂。您将发现自己必须手动跟踪比同步编程中更多的状态。

确保您的协议类可以处理任何大小的部分接收(需要其他状态),并且每个连接都有一个协议实例。

任何套接字错误都应导致连接关闭并清除状态。

并记录。一切。 TraceSource是你的朋友;通过编辑app.config,了解如何使用可以打开的.NET跟踪(即使在生产中)。

答案 2 :(得分:2)

我记不起对此特定场景的任何内置支持。但基本上我会这样做,通常被称为良好做法:

1)有一个线程池(大小 - 可能大约5)负责连接。这将从作业队列中读取(打开或关闭)并管理打开和关闭连接。

2)拥有一个用于管理通信和操作的线程池(中等大小)。我认为50的池应该没问题。

3)你将有一个线程负责编排整个操作,但不应该对任何操作进行错误处理,只对其他线程进行队列操作。

答案 3 :(得分:1)

只是为这里已经很好的答案添加一个“次要”的东西。

一个经常被忽视的领域是网卡本身的功能。确保服务器中的网络适配器支持TCP卸载。就此而言,支付一个好的,并验证驱动程序是最新的/最好的。

适配器内置的TCP卸载引擎工作在比代码更低的级别,并将处理从/向客户端转移数据的所有工作。这可能会对您的软件产生巨大的性能和可扩展性影响。

答案 4 :(得分:0)

答案 5 :(得分:0)

首先,使用其他人所说的异步方法。使用合理的硬件和合理的设计,1000个连接不应该是一个问题。

我有一个受单个编写器多个读取器锁保护的这些连接的集合。我可能每个连接都有一个计时器来处理轮询的周期性。当计时器触发时,我会向机顶盒发出请求,然后允许该连接上的异步读取累积响应,然后处理它。理想情况下,我会尝试避免访问连接集合并存储与连接相关的数据,以便可以在不锁定读取完成的情况下访问它。

我在博客中提到支持'很多'并发连接:http://www.serverframework.com/asynchronousevents/2010/10/how-to-support-10000-or-more-concurrent-tcp-connections---part-2---perf-tests-from-day-0.html重要的是,恕我直言,是为了确保你从一开始就测试这种负载,以便你可以快速发现你何时添加不能扩展的糟糕设计决策。