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

时间:2010-04-06 06:02:31

标签: c# performance sockets

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

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

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

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

  3. 有更有效/更好的方法吗?

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

好吧,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?好吧,如果你想调试,你可能想要在花时间查看收到的字节之前释放tcp连接。)

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:-1)

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