使用TCP时发送1个大块或大块小块是否更好?

时间:2009-03-20 12:55:03

标签: c sockets tcp

在我accept()连接,然后write()到客户端套接字之后,最好是一次编写要发送的所有数据还是以块的形式发送它?

例如:

  

接受,写1MB,断开连接

...或...

  

接受,写入256个字节,写入256个字节,... n,断开连接

我的直觉告诉我,底层协议会自动执行此操作,并进行错误更正等。这是正确的,还是我应该将数据分块?

在你问之前,不,我不确定我在哪里想到数据块 - 我认为这是我从编程C#web服务中获得的本能(为了克服接收缓冲区限制等等,我认为)。坏习惯?

注意:我正在使用C

7 个答案:

答案 0 :(得分:19)

客户端和服务器会根据需要分解您的数据,因此您可以在一个块中发送尽可能多的数据。查看Von Welch撰写的A User's Guide to TCP Windows文章。

答案 1 :(得分:7)

多年前,我有一个发送二进制数据的应用程序 - 它使用以下缓冲区的大小发送一个,然后另一个发送缓冲区(几百个字节)。在分析之后,我们发现我们可以通过将它们放入一个缓冲区并仅发送一次来获得主要的加速。我们感到很惊讶 - 即使每个数据包都有一些网络开销,我们也不认为这是一个值得注意的因素。

答案 2 :(得分:6)

从TCP级别开始,是的,当它太大时,你的大缓冲区将被拆分,当它太小时它将被合并。

从应用程序级别,不要让您的应用程序处理无限制的缓冲区大小。在某种程度上,你需要拆分它们。

如果您通过套接字发送文件,并且可能正在处理此文件的某些数据,例如压缩它。然后你需要把它分成几块。否则,当你最终发生在一个大文件上并且你的程序将没有RAM时,你将使用太多的RAM。

RAM不是唯一的问题。如果缓冲区太大,您可能会花太多时间读取数据或处理数据,而您将不会使用坐在那里等待数据的套接字。因此,最好有一个缓冲区大小的参数,以便您可以确定一个不太小,也不太大的值。

我的主张不是TCP套接字无法处理大量数据,它可以并且我建议在发送时使用更大的缓冲区以获得更高的效率。我的主张是不要在应用程序中处理无限制的缓冲区大小。

答案 3 :(得分:6)

通常在TCP套接字上启用的Nagle Algorithm可能会将这四个256字节写入组合到同一个数据包中。因此,如果您将其作为一个或多个写入发送并不重要,它应该最终会在一个数据包中结束。如果你有一个很大的块,那么将它作为一个块发送会更有意义。

答案 4 :(得分:3)

如果您在这些写入之间计算数据,最好在它们可用时对它们进行流式传输。此外,一次写入它们可能会产生缓冲区溢出(虽然这可能很少见,确实会发生),这意味着您的应用需要暂停并重新尝试写入(不是所有这些,只是从您遇到溢出的点开始) 。)

我通常不会忘记写入,特别是不要像256字节块一样小。 (由于在TCP / IP开销之后,大约1500字节可以容纳在以太网数据包中,我会使用至少那么大的块。)

答案 5 :(得分:1)

我会将所有的大块作为osi modell中的底层发送。因此,你不必担心你发送的大块大小,因为这些层会将它们分解为necisarry。

答案 6 :(得分:1)

唯一绝对的答案是在案例中分析app。有很多因素无法给出确切的答案,但在所有情况下都是正确的。