从套接字接收数据的C#性能方法?

假设我们有一个简单的互联网套接字,它将发送10兆字节(因为我想忽略内存问题)的随机数据。 是否应该使用任何性能差异或最佳实践方法来接收数据? 最终输出数据应由byte []表示。 是的,我知道向内存写入任意数量的数据是不好的,如果我正在下载一个大文件,我不会这样做。 但是出于论证的缘故,让我们忽略它,并假设它是一个少量的数据。 我也意识到这里的瓶颈可能不是内存管理而是套接字接收。 我只是想知道什么是最有效的接收数据的方法。

一些狡猾的方式可以想到的是:

  1. 有一个List和一个缓冲区,在缓冲区满了之后,将它添加到列表和结尾list.ToArray()以获取byte []

  2. 将缓冲区写入内存流后,在完成构造stream.Length的byte []之后,将其全部读入其中以获取byte []输出。

有没有更有效/更好的方法来做到这一点?

只需写入MemoryStream然后调用ToArray – 它可以为您构建适当大小的字节数组。 无论如何,这实际上是List样子,但使用MemoryStream会更简单。

好吧,Jon Skeet的答案很棒(像往常一样),但是没有代码,所以这是我的解释。 (对我来说很好。)

 using (var mem = new MemoryStream()) { using (var tcp = new TcpClient()) { tcp.Connect(new IPEndPoint(IPAddress.Parse("192.0.0.192"), 8880)); tcp.GetStream().CopyTo(mem); } var bytes = mem.ToArray(); } 

(为什么不using s组合这两个?好吧,如果你想调试,你可能想要在花时间查看收到的字节之前释放tcp连接。)

此代码将接收多个数据包并汇总其数据,FYI。 因此,这是一种简单地接收连接期间发送的所有tcp数据的好方法。

您的数据编码是什么? 它是纯ASCII,还是其他东西,如UTF-8 / Unicode?

如果它是纯ASCII,您可以只分配一个所需大小的StringBuilder()(从响应的ContentLength头获取大小)并继续将数据附加到构建器,然后使用Encoding.ASCII将其转换为字符串。

如果它是Unicode / UTF8,那么你有一个问题 – 你不能只在读取的字节上调用Encoding..GetString(buffer,0,bytesRead),因为bytesRead可能不构成该编码中的逻辑字符串片段。 对于这种情况,您需要将整个实体主体缓冲到内存(或文件)中,然后读取该文件并使用编码对其进行解码。

您可以写入内存流,然后使用流读取器或类似的东西来获取数据。 你在做什么数据? 我问,因为从内存的角度来看,在接收数据时将传入的数据写入文件或数据库表会更有效,而不是将整个内容存储在内存中。