.NET异步TcpListener/TcpClient问题

.NET异步TcpListener/TcpClient问题,.net,multithreading,sockets,tcp,tcplistener,.net,Multithreading,Sockets,Tcp,Tcplistener,对于如何正确实现TcpListner和TcpClient int.NET的异步方法,我有点不知所措。我已经阅读了很多关于hear的帖子,我相信我已经掌握了在服务器上接受新客户机的代码。以下是接受新连接的代码: Public Sub Start() m_oListener = New TcpListener(m_oIpAddress, m_iPort) m_oListener.Start() m_oListener.BeginAcceptTcpClient(New Asy

对于如何正确实现TcpListner和TcpClient int.NET的异步方法,我有点不知所措。我已经阅读了很多关于hear的帖子,我相信我已经掌握了在服务器上接受新客户机的代码。以下是接受新连接的代码:

Public Sub Start()
    m_oListener = New TcpListener(m_oIpAddress, m_iPort)

    m_oListener.Start()
    m_oListener.BeginAcceptTcpClient(New AsyncCallback(AddressOf OnAcceptClient), m_oListener)
End Sub

Public Sub OnAcceptClient(ByVal ar As IAsyncResult)
    Dim listener As TcpListener = CType(ar.AsyncState, TcpListener)
    Dim client As TcpClient = listener.EndAcceptTcpClient(ar)

    If listener.Server.IsBound Then
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf OnHandleClient), client)
        listener.BeginAcceptTcpClient(New AsyncCallback(AddressOf OnAcceptClient), listener)
    End If
End Sub
我不确定的是,一旦建立了连接,该如何处理客户端。据我所见,人们通常为每个连接的客户端创建一个新线程,以防止IO读取阻塞应用程序

我的应用程序将在任何给定时间连接多达100个客户端。如果我为每个客户端派生一个新线程,那么我将有100个左右的线程。对吗?我想我只是缺少了.NET框架中的异步方法

我看到的大多数示例都是让服务器接受连接,读入一条短消息(例如“hello server”),然后关闭客户端并关闭服务器。这并不能帮助我理解在很长一段时间内维护大量活动客户端的正确方法


提前感谢您的帮助。

您可以有100个线程,每个线程处理一个客户端,这样就可以了。您还可以有一个线程在所有客户机中循环并异步处理I/O

通过使其异步化,您不必担心单线程处理每个连接所花费的时间太长

如果您要扩展到比您所说的要高得多的级别,那么每个线程需要处理多个客户机

伪代码:

foreach TcpClient
    if DataAvailable
        BeginRead()

一旦在您的
OnAcceptClient
回调中提取了对
TcpClient
的引用,您将希望通过
GetStream
获取
网络流
,然后立即调用
BeginRead
(或
BeginWrite
)以启动异步操作。在从回调调用
EndRead
之后,您将链接下一个
BeginRead
,就像您使用
TcpListener

一样好吧,现在我明白了,我可能应该使用TcpClient.GetStream().BeginRead()异步读取流外的数据。如果使用BeginRead(),是否需要使用ThreadPool.QueueUserWorkItem?我看到的几个示例使用了线程轮询,但这里似乎不需要,因为我可以想象,当我使用BeginXXX和EndXXX方法时,.NET framework正在使用线程池。使用
BeginRead()
方法将已经将您放入线程池中,所以您已经准备好了。很好,感谢您的快速回复。我假设TcpClient.GetStream().BeginRead()是正确的选择(只需在调用EndRead()后再次调用它以保持输入)。假设有500个连接,最好的处理方法是什么?讨论是我真正想要的:代码不是必需的。@mlindegarde:好吧,这是处理所有这些连接的最好方法。使用
BeginRead
/
EndRead
将保留
ThreadPool
上的所有内容,因此您实际上不会专门使用任何一个显然不能很好扩展的线程。@mlindegarde-您将拥有一个
线程
,它可以连续循环通过
TcpClient
对象的集合(如我发布的伪代码)。通过使用
BeginRead()
不需要花很长时间就能打通每个客户机。@Brian-他仍然需要调用
BeginRead()
的东西,这就是I/O线程进入的地方。@Jon B:在AcceptClient上执行
中的初始
开始读取
,然后开始将其链接到
结束读取
回调,这样可以使泵继续运行。我已经有好几年没有这样做了,但我记得我就是这样做的。也许有什么我忘了?谢谢,我知道了。随着连接数量的增加,这种情况将如何扩展?假设它有500个用户,而不是100个。