关于多线程:如何在.NET中的线程上分散tcplistener的传入连接?

关于多线程:如何在.NET中的线程上分散tcplistener的传入连接?

How to spread tcplistener incoming connections over threads in .NET?

使用Net.Sockets.TcpListener时,在单独的线程中处理传入连接(.AcceptSocket)的最佳方法是什么?

这个想法是当新的传入连接被接受时启动一个新线程,而tcplistener则可用于其他传入连接(并为每个新的传入连接创建一个新线程)。与发起连接的客户端的所有通信和终止将在线程中处理。

赞赏VB.NET代码的示例C#。


我一直在使用的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Server
{
  private AutoResetEvent connectionWaitHandle = new AutoResetEvent(false);

  public void Start()
  {
    TcpListener listener = new TcpListener(IPAddress.Any, 5555);
    listener.Start();

    while(true)
    {
      IAsyncResult result =  listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);
      connectionWaitHandle.WaitOne(); // Wait until a client has begun handling an event
      connectionWaitHandle.Reset(); // Reset wait handle or the loop goes as fast as it can (after first request)
    }
  }


  private void HandleAsyncConnection(IAsyncResult result)
  {
    TcpListener listener = (TcpListener)result.AsyncState;
    TcpClient client = listener.EndAcceptTcpClient(result);
    connectionWaitHandle.Set(); //Inform the main thread this connection is now handled

    //... Use your TcpClient here

    client.Close();
  }
}

我相信您可以通过与.NET中任何其他异步操作相同的方式来执行此操作:您调用该方法的BeginXxx版本,在本例中为BeginAcceptSocket。您的回调将在线程池上执行。

池化线程的可伸缩性通常比每个连接的线程好得多:一旦获得几十个连接,系统在线程之间进行切换的工作要比完成实际工作困难得多。此外,每个线程都有自己的堆栈,堆栈大小通常为1MB(尽管取决于链接标志),必须在2GB虚拟地址空间(在32位系统上)中找到该堆栈;实际上,这会将您限制为少于1000个线程。

我不确定.NET \\的线程池当前是否使用它,但是Windows有一个称为I / O完成端口的内核对象,该对象有助于可伸缩的I / O。您可以将线程与此对象关联,并且I / O请求(包括接受传入的连接)可以与其关联。当I / O完成(例如连接到达)时,Windows将释放等待线程,但前提是当前可运行线程的数量(由于其他原因未被阻止)小于完成端口配置的可扩展性限制。通常,您会将其设置为内核数的一小部分。


我想提出一种不同的方法:
我的建议仅使用两个线程。
*一个线程检查传入的连接。
*当打开新连接时,此信息将写入包含所有当前打开的连接的共享数据结构。
*第二个线程枚举该数据结构,并为每个打开的连接接收已发送的数据并发送答复。

此解决方案在线程方面更具可伸缩性,如果正确实施,则应具有更好的性能,然后在每个打开的连接中打开一个新线程。


O \\'Reilly C#3.0 Cookbook中有一个很好的例子。您可以从http://examples.oreilly.com/9780596516109/CSharp3_0CookbookCodeRTM.zip

下载随附的源代码


我会使用线程池,这样您就不必每次都启动一个新线程(因为这有点贵)。我也不会无限期地等待进一步的连接,因为客户端可能不会关闭其连接。您打算如何计划每次将客户端路由到同一线程?

对不起,没有样品。


推荐阅读

    linux命令连接光驱?

    linux命令连接光驱?,系统,位置,设备,数据,电脑,服务,资料,盘中,智能,管理,Lin

    linux命令行拨号连接?

    linux命令行拨号连接?,系统,网络,软件,手机,服务,密码,地址,名称,电话号码,

    linux线程查询命令?

    linux线程查询命令?,系统,第一,线程,命令,软件,名称,信息,进程,选项,方法,Lin

    linux命令逻辑连接符?

    linux命令逻辑连接符?,系统,网络,名字,环境,信息,名称,设备,发行,位置,较大,L

    linux跳板机连接命令?

    linux跳板机连接命令?,地址,服务,密码,工具,中国,网络,位置,系统,电脑,在线,

    linux连接外网命令?

    linux连接外网命令?,网络,系统,工具,情况,软件,信息,地址,代理,地方,数据,请

    linux命令连接ip?

    linux命令连接ip?,地址,系统,网络,工作,信息,命令,密码,名称,设备,服务,linux

    linux多线程下载命令?

    linux多线程下载命令?,软件,工具,平台,中心,系统,代理,网络,网站,手机,官方

    linux断开线程命令?

    linux断开线程命令?,系统,状态,工作,代码,线程,入口,网络,管理,名称,命令,lin

    linux命令连接网址?

    linux命令连接网址?,网址,系统,地址,服务,传播,数据,命令,名字,环境,网站,如

    linux连接多条命令?

    linux连接多条命令?,工具,情况,命令,分行,服务,地址,连续,终端,窗口,主机,lin

    linux有线网连接命令?

    linux有线网连接命令?,系统,网络,软件,电脑,密码,地址,信息,虚拟机,终端,命

    linux编译连接命令?

    linux编译连接命令?,系统,代码,环境,工具,文件,资料,电脑,百度,终端,命令,在l

    linux停止线程的命令?

    linux停止线程的命令?,系统,软件,代码,产品,进程,第一,管理,生产,通信,工具,l

    linux超线程查看命令?

    linux超线程查看命令?,系统,第一,信息,软件,命令,数据,工具,实时,界面,个数,L

    linux查看多线程命令?

    linux查看多线程命令?,系统,第一,线程,地址,数据,进程,命令,名称,软件,情况,

    linux上的软连接命令?

    linux上的软连接命令?,系统,设备,位置,链接,文件,数据,交通,地方,信息,地址,L

    linux执行线程命令?

    linux执行线程命令?,系统,工作,线程,软件,服务,管理,信息,环境,名称,命令,lin

    mac命令连接linux?

    mac命令连接linux?,系统,软件,电脑,密码,公司,网络,地址,通用,服务,发展,macb

    远程连接命令linux?

    远程连接命令linux?,服务,系统,密码,网络,软件,名称,电脑,资料,地址,信息,远