我正在用编写服务器/客户端项目
TcpClient
和
NetworkStream
物体。我希望许多客户端连接到服务器,这些客户端存储在
List<>
自定义的
NetworkNode
对象,每个对象都有
TCP客户端
和一个
网络流
用于与相应的客户端通信。
服务器需要能够保持与客户端的连接,并在收到消息后立即(快速)等待和操作消息。同步轮询对于这个应用程序来说是非常不可取的,我也不想这样编码。
当前,服务器正在异步接受客户端并将它们添加到
列表<>
,工作非常顺利。我已经用一个控制台应用程序测试了这一点,该应用程序生成了多达100个客户端,并在极短的时间内(<1秒)以环回地址连接到服务器。
将客户端添加到
列表<>
对象使用
GetStream()
方法返回客户端的
网络流
对象我正在尝试使用
NetworkStream.BeginRead()
方法来实现来自每个TCP客户端的异步数据接收。对该方法的第一次调用如下:
this.Stream.BeginRead(readBuffer, readBufferOffset, readBuffer.Length - readBufferOffset,
new AsyncCallback(nodeStreamReadCallback), this.Stream);
因为控制台测试应用程序一连接到服务器就发送一些数据
readCallback(IAsyncResult)
方法几乎立即调用:
private void readCallback(IAsyncResult ar)
{
NetworkStream _stream = (NetworkStream)ar.AsyncState;
int _bytesRead = 0;
_bytesRead = _stream.EndRead(ar);
this.Stream.Write(readBuffer, readBufferOffset, _bytesRead);
//increase buffer offset value
readBufferOffset += _bytesRead;
//TODO process the received data
...
//wait for the next chunk of data
this.Stream.BeginRead(readBuffer, readBufferOffset, readBuffer.Length - readBufferOffset,
new AsyncCallback(readCallback), this.Stream);
}
我正在执行第二次呼叫
Stream.BeginRead()
目的是等待下一个数据块到达或变得可用。
当我对
Stream.BegginRead()
一切都很顺利。所有数据都被接收并发送回每个客户端,没有延迟,线程使用量极低(过程中平均增加2到3个线程)。
然而,即使只有
单个客户端
已连接,如果我尝试
第二次呼叫
到
Stream.BegginRead()
在
readCallback()
我遇到的方法
大量的
竞争问题。对于单个客户端,第二次调用后的CPU使用率从约0%跳到30%到60%之间,线程数可以从11跳到35。
所以这是一个线程或递归问题,我觉得当我不在的时候,我应该等待一些东西,但我无法完全理解这里发生的事情。这与我在
TcpListener.BeginAcceptTcpClient()
所以我认为它的运作方式一定不同。
我感谢您可能提供的任何和所有建议,并提前感谢您的帮助!