Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用TCP时,发送一个大数据块还是发送很多小数据块更好?_C_Sockets_Tcp - Fatal编程技术网

使用TCP时,发送一个大数据块还是发送很多小数据块更好?

使用TCP时,发送一个大数据块还是发送很多小数据块更好?,c,sockets,tcp,C,Sockets,Tcp,在我accept()一个连接,然后write()到客户端套接字之后,是一次写入所有要发送的数据,还是分块发送 例如: 接受、写入1MB、断开连接 ……或者 接受,写入256字节,写入256字节,…n,断开连接 我的直觉告诉我,底层协议会自动执行此操作,并进行纠错等。这是正确的,还是我应该对数据进行分块 在你提问之前,不,我不确定我是从哪里得到了数据块的想法——我认为这是我从编程C#web服务(我认为是为了绕过接收缓冲区限制等)中获得的本能。坏习惯 注意:我使用的是C客户端和服务器将根据需要分解数

在我
accept()
一个连接,然后
write()
到客户端套接字之后,是一次写入所有要发送的数据,还是分块发送

例如:

接受、写入1MB、断开连接

……或者

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

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

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


注意:我使用的是C

客户端和服务器将根据需要分解数据,因此您可以在一个数据块中发送任意数量的数据。查看Von Welch的文章。

从TCP级别看,是的,当缓冲区太大时,您的大缓冲区将被拆分,当缓冲区太小时,它将被合并

从应用程序级别来看,不要让应用程序处理无限的缓冲区大小。在某种程度上,你需要把他们分开

如果您正在通过套接字发送一个文件,并且可能正在处理该文件的一些数据,比如压缩它。然后你需要把它分成几块。否则,当您最终遇到一个大文件时,您将使用过多的RAM,并且您的程序将耗尽RAM

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


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

多年前,我有一个发送二进制数据的应用程序——它使用以下缓冲区的大小进行一次发送,然后使用缓冲区(几百字节)进行另一次发送。在分析之后,我们发现我们可以通过将它们放在一个缓冲区中并只发送一次来获得更大的速度。我们很惊讶——尽管每个数据包上都有一些网络开销,但我们认为这不是一个值得注意的因素。

我会在一个大数据块中发送所有数据包,作为数据包中的底层。因此,您不必担心发送的数据块有多大,因为层会根据需要将这些数据块拆分。

如果您正在计算这些写入之间的数据,最好在它们可用时对其进行流式处理。此外,一次写入所有内容可能会导致缓冲区溢出(虽然这种情况可能很少见,但确实会发生),这意味着您的应用程序需要暂停并重新尝试写入内容(不是所有内容,只是从发生溢出的位置开始)


我通常不会特意对写操作进行分块,特别是不会小到256字节的分块。(由于在TCP/IP开销之后,一个以太网数据包可以容纳大约1500个字节,所以我会使用至少那么大的数据块。)

唯一绝对的答案是在这种情况下分析应用程序。由于因素太多,不可能给出所有情况下都正确的确切答案。

通常在TCP套接字上默认启用,它可能会将这四个256字节的写入合并到同一个数据包中。所以,不管你是一次还是多次发送,它都应该以一个包的形式结束。如果一开始就有一个大数据块,那么将其作为一个数据块发送会更有意义。

TCP/IP不基于oSI模型oSI模型虽然不准确,但在描述网络协议时仍然很有用。TCP/IP堆栈很好地映射到OSI模型中,一直映射到TCP/UDP层。OSI模型不应该与没有人使用的OSI堆栈混淆。我们将不得不对一个不准确的模型的有用性持不同意见。我在这里误解了一些非常基本的东西了吗?TCP位于OSI模型的第4层,而IP位于第3层。把这两个因素放在一起,我们得到了TCP/IP,它现在被用于大多数网络上的数据传输。不,OSI对TCP/IP没有任何影响——证据是TCP/IP确实有效。您可以将TCP/IP的某些位映射到OSI模型的位,这一事实证明不了什么。这是一个很好的观点,特别是如果应用程序一次处理“n”字节的数据。我已经在无数应用程序中看到,使用更大的缓冲区总是会导致整体更高的传输速率。我还看到,当使用太大的缓冲区时,应用程序的传输速度实际上会变慢,因为您没有足够快地向应用程序提供数据socket@Brian,在我们的例子中,合并在一起的两个数据包的大小通常小于一个TCP/IP数据包。在实践中,当使用较大的缓冲区时,我总是看到速度显著提高。也许这与内部操作系统缓冲区复制有关,而与TCP无关。好吧,对于执行的每个发送/写入,您必须执行内核模式切换,IIRC大约为100个周期。因此,如果您经常这样做,那么开销可能会成为一个问题,您宁愿在一个系统调用中完成所有需要完成的工作。