简体   繁体   English

异步线程tcp服务器

[英]Async threaded tcp server

I want to create a high performance server in C# which could take about ~10k clients. 我想用C#创建一个高性能服务器,可能需要大约10万个客户端。 Now i started writing a TcpServer with C# and for each client-connection i open a new thread. 现在我开始用C#编写TcpServer,并为每个客户端连接打开一个新线程。 I also use one thread to accept the connections. 我还使用一个线程来接受连接。 So far so good, works fine. 到目前为止这么好,工作正常。

The server has to deserialize AMF incoming objects do some logic ( like saving the position of a player ) and send some object back ( serializing objects ). 服务器必须反序列化AMF传入对象做一些逻辑(比如保存播放器的位置)并发回一些对象(序列化对象)。 I am not worried about the serializing/deserializing part atm. 我并不担心序列化/反序列化部分atm。

My main concern is that I will have a lot of threads with 10k clients and i've read somewhere that an OS can only hold like a few hunderd threads. 我主要担心的是,我将拥有10k个客户端的大量线程,而且我已经读过某个操作系统只能保持几个hunderd线程的地方。

Are there any sources/articles available on writing a decent async threaded server ? 有没有关于编写体面的异步线程服务器的资料/文章? Are there other possibilties or will 10k threads work fine ? 还有其他可能性还是10k线程可以正常工作? I've looked on google, but i couldn't find much info about design patterns or ways which explain it clearly 我看过谷歌,但我找不到很多关于设计模式或清楚解释的方法的信息

You're going to run into a number of problems. 你会遇到很多问题。

  1. You can't spin up 10,000 threads for a couple of reasons. 出于几个原因,您无法启动10,000个线程。 It'll trash the kernel scheduler. 它会破坏内核调度程序。 If you're running a 32-bit, then the default stack address space of 1MB means that 10k threads will reserve about 10GB of address space. 如果您运行的是32位,则默认堆栈地址空间为1MB意味着10k线程将保留大约10GB的地址空间。 That'll fail. 那会失败。

  2. You can't use a simple select system either. 您也不能使用简单的选择系统。 At it's heart, select is O(N) for the number of sockets. 在它的核心,选择是O(N)的插座数量。 With 10k sockets, that's bad. 有10k插座,这很糟糕。

  3. You can use IO Completion Ports. 您可以使用IO完成端口。 This is the scenario they're designed for. 这是他们设计的场景。 To my knowledge there is no stable, managed IO Completion port library. 据我所知,没有稳定的托管IO完成端口库。 You'll have to write your own using P/Invoke or Managed C++. 您必须使用P / Invoke或Managed C ++编写自己的代码。 Have fun. 玩得开心。

The way to write an efficient multithreaded server is to use I/O completion ports (using a thread per request is quite inefficient, as @Marcelo mentions). 编写高效多线程服务器的方法是使用I / O完成端口(每个请求使用一个线程是非常低效的,如@Marcelo所提到的)。

If you use the asynchronous version of the .NET socket class, you get this for free. 如果您使用.NET套接字类的异步版本,则可以免费获得。 See this question which has pointers to documentation. 请参阅此问题 ,其中包含指向文档的内容。

You definitely don't want a thread per request. 你绝对不希望每个请求都有一个帖子。 Even if you have fewer clients, the overhead of creating and destroying threads will cripple the server, and there's no way you'll get to 10,000 threads; 即使您拥有较少的客户端,创建和销毁线程的开销也会削弱服务器,并且您无法获得10,000个线程; the OS scheduler will die a horrible death long before then. 操作系统调度程序很久就会死于可怕的死亡。

There are numerous articles online about asynchronous server programming in C# (eg, here ). 网上有很多关于C#中异步服务器编程的文章(例如, 这里 )。 Just google around a bit. 只是google一下。

You want to look into using IO completion ports . 您想要研究使用IO完成端口 You basically have a threadpool and a queue of IO operations. 您基本上有一个线程池和一个IO操作队列。

I/O completion ports provide an efficient threading model for processing multiple asynchronous I/O requests on a multiprocessor system. I / O完成端口提供了一种有效的线程模型,用于处理多处理器系统上的多个异步I / O请求。 When a process creates an I/O completion port, the system creates an associated queue object for requests whose sole purpose is to service these requests. 当进程创建I / O完成端口时,系统会为请求创建关联的队列对象,这些请求的唯一目的是为这些请求提供服务。 Processes that handle many concurrent asynchronous I/O requests can do so more quickly and efficiently by using I/O completion ports in conjunction with a pre-allocated thread pool than by creating threads at the time they receive an I/O request. 处理许多并发异步I / O请求的进程可以通过将I / O完成端口与预分配的线程池结合使用,而不是在接收I / O请求时创建线程,从而更快速有效地执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM