C#等待来自NetworkStream

时间:2018-02-13 18:23:35

标签: c# networking stream

我正在使用一个使用TcpListener对象的异步TCP服务器类。我对BeginAcceptTcpClient使用TcpListener方法,当回调触发并EndAcceptTcpClient时,我得到一个TcpClient对象。为了接收和发送此TcpClient,我需要使用客户端对象提供的NetworkStream

我使用NetworkStream的方式虽然感觉不对。我调用BeginRead和回调最终使用EndRead,但这要求我使用byte[]缓冲区。到目前为止,这对我来说运作良好,但我不得不怀疑是否有更清洁的做事方式。我目前的流程如下:receive data into a byte[] bufferthrow data into a MemoryStreamuse a BinaryReader to get the data that I'm passing,然后我最终可以得到我的协议所需的内容。

是否有更优雅的方式从NetworkStream转到BinaryReader(最终BinaryWriter,因为我要按照收到的数据传回数据)?我必须首先将其转储到byte[],然后转换为MemoryStream(复制数据吗?),然后最终能够创建读取器/写入器对象,这是浪费的。

我选择使用BinaryReader创建BinaryWriter / NetworkStream,但是从我收集的内容来看,这些对象需要一个包含以前可用数据的流。似乎我只需要通知某种方式即可获得NetworkStream数据可用而无需读入缓冲区。也许我错了,这正是NetworkStreams应该如何使用的。如果我不必将缓冲区从一个流复制到另一个流中,那么事情似乎可以更加简化。

编辑:

以下是相关来源的示例:

public class Server
{
  TcpListener listener;
  const int maxBufferSize = 0xFFFF;
  byte[] clientBuffer = new byte[maxBuffersize];

  public Server(IPAddress address, int port)
  {
    listener = new TcpListener(address, port);
  }

  public void Start()
  {
    listener.Start();
    listener.BeginAcceptTcpClient(OnAccept, listener);
  }

  public void Stop()
  {
    listener.Stop();
  }

  private void OnAccept(IAsyncResult ar)
  {
    TcpListener listener = ar.AsyncState as TcpListener;
    TcpClient client = listener.EndAcceptTcpClient(ar);
    client.GetStream().BeginRead(clientBuffer, 0, maxBufferSize, OnReceive, client);    
    listener.BeginAcceptTcpClient(OnAccept, listener);
  }

  private void OnReceive(IAsyncResult ar)
  {
    TcpClient client = ar.AsyncState as TcpClient;
    int len = client.GetStream().EndRead(ar);
    if (len == 0)
    {
      client.Close();
      return;
    }
    else
    {
      MemoryStream inStream = new MemoryStream(len == maxBufferSize ? clientBuffer : clientBuffer.Take(len).ToArray());
      MemoryStream outStream = DoStuff(inStream); //Data goes off to the app at this point and returns a response stream
      client.GetStream().Write(outStream.ToArray(), 0, outStream.Length);
      inStream.Dispose();
      outStream.Dispose();
    }
  }
}

我的问题围绕着OnReceive中发生的事情。您将看到我使用EndRead完成读取操作,此时我现在可以从Server类的byte []字段中检索数据。我担心的是,将数据从NetworkStream复制到数组,然后再复制到MemoryStream所花费的时间是浪费的(至少感觉就是这样,也许C#可以有效地处理这些东西?)

提前致谢。

0 个答案:

没有答案