通过单个发送呼叫发送的合理数据量

时间:2014-07-15 15:18:52

标签: c windows send

我需要通过TCP套接字将不同大小的文件发送给其他客户端。现在我想知道一个发送函数调用有多少数据是合理的?

例如,我不会发送一个完整的2兆字节图片,其中1个调用发送 - 我要将该文件切换成较小的缓冲区并一个接一个地发送它们。但这些缓冲区应该有多小或多大?我知道发送不保证发送我的所有数据 - 我会检查。

2 个答案:

答案 0 :(得分:1)

只要您发送大于MTU的缓冲区(通常略低于1500字节左右),这并不重要。如果发送大于MTU的缓冲区,操作系统或NIC会将数据包分段为MTU大小的数据包,您不必担心自己会进行碎片处理。当发生这种情况时,操作系统将阻止对send()的呼叫,直到所有数据都已发送或发生错误 - 如果您愿意,您可以在一个呼叫中发送所有2 MB,这不会是一个问题

如果仅仅因为缓存效应(即由于数据并非全部适合L2缓存,您将有更多缓存未命中),您可能会因为一个非常大的调用而不是一个比MTU更大的调用而获得稍差的性能),但这可能不是很重要。

但是,对于文件传输,如果使用TransmitFile()函数,实际上会获得更好的性能,而不是手动将文件中的数据读入缓冲区然后发送它。该功能针对文件传输进行了高度优化,因为它可以将文件数据直接从文件系统DMA到NIC上,而无需将其从内核空间复制到用户空间,然后再返回到内核空间。这称为zero-copy operation

答案 1 :(得分:0)

正在执行send()的主题的响应能力决定了通过单个send()调用发送的数据的大小

  1. 如果您的帖子除了send()之外没有任何其他功能,您无需斩断数据,您可以一次性发送整个数据并让操作系统执行此操作。神奇的。在这种情况下,send()调用在整个数据发送之前不会返回,因此您的线程无法响应/执行任何其他操作。

  2. 另一方面,如果您希望执行send()的线程具有响应能力,则需要将数据分解为较小的缓冲区。这样,您的线程在每个部分缓冲区的send()之后获得执行时间。缓冲区的大小应直接取决于您拥有的数据速度,与预期的响应速度成反比。