【问题标题】:C# performance methods of receiving data from a socket?从套接字接收数据的 C# 性能方法?
【发布时间】:2017-05-26 22:54:06
【问题描述】:

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

能想到的几个狡猾的方法是:

  1. 有一个List和一个buffer,buffer满后,加入list中,在list.ToArray()末尾获取byte[]

  2. 将缓冲区写入内存流,完成后构造流的字节[].Length并将其全部读入其中以获得字节[]输出。

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

【问题讨论】:

    标签: c# performance sockets


    【解决方案1】:

    只需写信给MemoryStream,然后调用ToArray——它会为您构建一个适当大小的字节数组。这实际上就是 List<byte> 的样子,但使用 MemoryStream 会简单得多。

    【讨论】:

    • 是的,这似乎是最简单但最好的答案,谢谢!
    【解决方案2】:

    好吧,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();
    }
    

    (为什么不将两个usings 结合起来呢?好吧,如果你想调试,你可能想在花时间查看收到的字节之前释放 tcp 连接。)

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

    【讨论】:

      【解决方案3】:

      您的数据的编码是什么?是普通的 ASCII,还是其他的东西,比如 UTF-8/Unicode?​​p>

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

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

      【讨论】:

      • 它只是 ASCII 是的,这是个好主意!!!为什么其他编码需要全量才能正确转换?
      • 哦,因为如果他们每个字符使用 2 个字节,那么如果您收到 7 个字节并尝试转换它,就会出现问题。但是你可以只得到 0-6 并缓冲 1 不是吗?更多的工作,但更少的内存压力
      【解决方案4】:

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

      【讨论】:

      • 可能将其转换为字符串
      猜你喜欢
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多