问题描述
我正在维护一些通过 TCP 套接字发送数据的成熟生产代码。它总是将大块数据分成许多数据包,每个数据包 1000 字节。我只是想知道为什么要这样做。为什么我不能一次性将一个 GB 的字节数组写入套接字?这样做有什么缺点?
解决方法
根据底层实现,尝试批量发送 1GB 可能会导致 1GB 被复制到某个缓存中,然后在那里保留一段时间。因此,如果没有足够的可用内存(即使有足够的可用内存 - 这可能不是利用它的最有效方式),这可能是一个问题。
虽然“手动”将其分成 1000 个字节的段,但对我来说听起来有点矫枉过正。
,有很多理由不要一次投入一大块。
首先:即使在非常快的网络上发送一 GB 数据也需要很长的时间。在 10Gbps 网络上,它需要不到 1 秒的时间,这在计算机语言中是很长的时间。并且假设这一项操作拥有网络的所有可用带宽,并且不必与其他任何东西共享。
这意味着,如果您成功地对 TCP 套接字进行了 1GB write
调用,则需要一段时间才能真正发送后面的数据位。
同时,您必须将所有数据保存在内存中。这意味着您需要为整个事务分配并保留 1GB 的数据。
如果您在每次写入之前填充一个小缓冲区并从源中读取(或生成,取决于数据的来源),那么您将只需要一点内存(缓冲区的大小)。
对于今天的机器来说,所有这些听起来可能没什么大不了的,但考虑到许多服务器将同时为数百个客户端/请求提供服务,如果每个服务器都需要 1GB 的缓冲区,那么这可能会很快失控。
1000 是否适合该缓冲区的大小?我不是网络专家,但我怀疑这有点低。也许 64k 左右的东西是合适的,但其他人可以在这里提供更好的细节。找到合适的缓冲区大小有时会有点棘手。