不使用线程处理多个 TcpClient 连接

发布于 2024-10-30 06:31:29 字数 643 浏览 4 评论 0原文

我有一个 C# 程序,其中有很多(假设大约一千个)打开的 TcpClient 对象。我想进入一种状态,等待任何这些连接发生某些事情。

我宁愿不为每个连接启动一个线程。

类似...

while (keepRunning)
{
     // Wait for any one connection to receive something.
     TcpClient active = WaitAnyTcpClient(collectionOfOpenTcpClients);

     // One selected connection has incomming traffic. Deal with it.
     // (If other connections have traffic during this function, the OS
     // will have to buffer the data until the loop goes round again.)
     DealWithConnection(active);
}

附加信息:
TcpClient 对象来自 TcpListener。
目标环境将是 MS .NET 或 Mono-on-Linux。
该协议要求连接打开时长时间处于空闲状态。

I've got a C# program with lots (let's say around a thousand) opened TcpClient objects. I want to enter a state which will wait for something to happen for any of those connections.

I would rather not launch a thread for each connection.

Something like...

while (keepRunning)
{
     // Wait for any one connection to receive something.
     TcpClient active = WaitAnyTcpClient(collectionOfOpenTcpClients);

     // One selected connection has incomming traffic. Deal with it.
     // (If other connections have traffic during this function, the OS
     // will have to buffer the data until the loop goes round again.)
     DealWithConnection(active);
}

Additional info:
The TcpClient objects come from a TcpListener.
The target environment will be MS .NET or Mono-on-Linux.
The protocol calls for long periods of idleness while the connection is open.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

看透却不说透 2024-11-06 06:31:29

您尝试做的事情在 Microsoft 术语中称为异步模式。总体思路是将所有I/O阻塞操作改为非阻塞。如果这样做,应用程序通常需要与机器上的 CPU 内核一样多的系统线程。

看一下 .Net 4 中的任务并行库:
http://msdn.microsoft.com/en-us /library/dd460717%28VS.100%29.aspx

这是一个非常成熟的包装器,覆盖了普通的旧 Begin/Callback/Context .Net 范例。

更新:

想想从连接读取数据后您将如何处理数据。在现实生活中,您可能必须回复客户端或将数据保存到文件中。在这种情况下,您将需要一些 C# 基础设施来包含/管理您的逻辑,并且仍然保留在单个线程中。 TPL 免费为您提供。它唯一的缺点是它是在 .Net 4 中引入的,所以可能还没有在 Mono 中。

另一件需要考虑的事情是连接的生命周期。您的连接打开/关闭的频率以及它们的寿命有多长?这很重要,因为接受和断开 TCP 连接需要与客户端进行数据包交换(这本质上是异步的,而且恶意客户端可能根本不会返回 ACK(已知)数据包)。如果您认为这方面对您的应用程序很重要,您可能需要研究如何在 .Net 中正确处理此问题。在WinAPI中对应的函数是AcceptEx和DisconnectEx。可能它们是用 Begin/End 方法封装在 .Net 中的 - 在这种情况下你就可以开始了。否则,您可能必须为这些 WinAPI 调用创建一个包装器。

What you're trying to do is called an Async Pattern in Microsoft terminology. The overall idea is to change all I/O blocking operations to non-blocking. If this is done, the application usually needs as many system threads as there are CPU cores at the machine.

Take a look at Task Parallel Library in .Net 4:
http://msdn.microsoft.com/en-us/library/dd460717%28VS.100%29.aspx

It's a pretty mature wrapper over the plain old Begin/Callback/Context .Net paradigm.

Update:

Think about what to you will do with the data after you read from the connection. In real life you probably have to reply to the client or save the data to a file. In this case you will need some C# infrastructure to contain/manage your logic and still stay within a single thread. TPL provides it to you for free. Its only drawback is that it was introduced in .Net 4, so probably it's not in Mono yet.

Another thing to consider is connection's lifetime. How often your connections are opened/closed and how long do they live? This is important because accepting and disconnecting a TCP connection requires packet exchange with the client (which is asynchronous by nature, and moreover - a malicious client may not return ACK(-nowledged) packets at all). If you think this aspect is significant for your app, you may want to research how to handle this properly in .Net. In WinAPI the corresponding functions are AcceptEx and DisconnectEx. Probably they are wrapped in .Net with Begin/End methods - in this case you're good to go. Otherwise you'll probably have to create a wrapper over these WinAPI calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文