在C语言中发送数据建议的分块大小是多少?

3

我有一个服务器需要每次请求传输大量数据(约1-2GB)。每个send调用的推荐数据量是多少?这个有关系吗?


2
答案取决于几个因素:文件系统块大小和客户端与服务器之间的PMTU。如果从PMTU中减去数据包头,那么使用小于或等于该值的文件系统块大小的最大倍数。 - cdhowie
进行实验并选择最佳尺寸。 - alinsoar
2
我可能会选择与MTU大小相等或更小的东西,甚至可能是其80%,以避免网络内分段。你只是在局域网上吗?还是你试图跨越互联网? - jedwards
@jedwards 这是用来通过互联网传输的 - chacham15
@jedwards 如何?他如何发现路径 MTU,又如何向 TCP 指定数据包大小?如果 TCP/IP 栈不能将数据组织成 MTU 大小的数据包,那你认为它的作用是什么? - user207421
@EJP 这种方法在通过互联网传输时并不是一个好的选择,因为PMTU可能会发生变化 - 我希望这是针对局域网或受控环境,在那里PMTU将相对稳定。无论如何,您可以设置"不分段"位并尝试玩弄有效载荷大小来发现PMTU。如果您在'send'命令中指定小于TCP缓冲区的长度,它将恰好发送指定数量的有效载荷字节。至于最后一个问题,它真的超出了评论回复的范围,但涉及许多事情。 - jedwards
2个回答

1

您的数据包大小受协议的最大传输单元(MTU)限制。如果发送的数据包大于MTU,则会出现数据包分段。

您可以进行一些计算:http://www.speedguide.net/articles/mtu-what-difference-does-it-make--111 更多参考资料:http://en.wikipedia.org/wiki/Maximum_transmission_unit

但是,我的建议是,如果您的目标是足够好,并且只需让操作系统网络层完成其工作,除非您正在编程原始套接字或传递某些奇怪的选项,否则通常操作系统将具有网络缓冲区并尽力而为。

考虑到这个最后的选项,那么socket.send()不过是从用户进程内存到内核私有内存的内存传输。经验法则是不要超过虚拟内存页面大小http://en.wikipedia.org/wiki/Page_(computer_memory,通常为4KB。


是的,我认为可能有一个缓冲区来处理这个问题,但我不确定。不过,发送多少数据才算是“合理”的呢? - chacham15
不能“发送大于MTU的数据包并获得分段数据包”。TCP/IP协议栈不会这样做。套接字发送缓冲区应该比4k大得多,最好是64k-1。 - user207421

1
TCP/IP协议栈负责确保不发送大于路径MTU的数据包,而要使其发送比MTU更小的数据包,则需要付出相当大的努力,而且这种方式对吞吐量没有帮助。对于任何给定的连接,没有发现路径PTU实际上是什么的方法。因此,请将所有关于路径MTU的考虑排除在外。
您可以并且应该尽可能地使每个send()都尽可能大。

我可以让send()函数发送1-2GB的数据,但由于内存带宽的限制这也是不合理的。那么中间点在哪里呢? - chacham15
@chacham15 这是因为内存使用而不是“内存带宽”,所以选择适合您内存预算的缓冲区。我通常使用8192,但如果可以抽出更多空间,也可以使用1兆字节。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接