TCP套接字发送缓冲区大小效率

当使用WinSock或POSIX TCP套接字(在C / C ++中,所以不需要额外的Java / Python / etc。wrap)时,是否有任何效率利/弊build立一个更大的缓冲区(例如高达4KB)尽可能less的调用来发送缓冲区,直接与数据位(比如1-1000字节)进行多个较小的调用,而对于非阻塞/asynchronous套接字,单个缓冲区对我来说可能更容易pipe理。

我知道与recv小缓冲区不build议,但我找不到任何发送。

例如,每个发送通用平台上的呼叫进入内核模式? 一个1字节的发送实际上是否会导致在正常情况下发送一个1字节的数据包?

正如Richard Stevens在“ TCP插图第一卷”中解释的那样,TCP将发送缓冲区分成接近最佳的段,以适应沿着到另一个TCP对等点的路径的最大分组大小。 这意味着它永远不会尝试发送将通过ip沿着路由到达目的地的碎片的分段(当分组在某个ip路由器处被分段时,它发回一个IP分段ICMP分组,并且TCP将考虑到它以减少MSS为此连接)。 也就是说,没有必要比你在路径上的链路​​级接口的最大数据包大小更大的缓冲区。 有一个,比方说,两次或三次,让你确信TCP不会停止发送,只要它收到远程对端的确认,因为没有缓冲区填充数据。

认为正常的接口类型是以太网,并且它的最大数据包大小为1500字节,所以通常TCP不会发送大于此大小的段。 它通常每个连接有8Kb的内部缓冲区,所以在内核空间添加缓冲区大小(如果这是在内核空间中具有缓冲区的唯一原因)没什么意义。

当然,还有其他一些因素会迫使你在用户空间中使用一个缓冲区(例如,你想要将数据存储到某个地方发送到你的对等进程,因为内核空间中只有8Kb的数据需要缓冲,你需要更多的空间可以做一些其他的进程)例如:ircd(因特网中继聊天守护进程)使用高达100Kb的写入缓冲区,因为对方没有接收/确认数据。 如果你只写(2)连接,一旦内核缓冲区满了,你将会等待,也许这不是你想要的。

在用户空间中有缓冲区的原因是因为TCP也使流量控制,所以当它不能发送数据时,它必须放在某个地方来应付它。 您必须决定是否需要您的过程来将数据保存到极限,或者您可以阻止发送数据直到接收器能够再次接收。 内核空间中的缓冲区大小是有限的,并且对于用户/开发人员而言通常是失控的。 用户空间中的缓冲区大小仅受限于其允许的资源。

在TCP连接中接收/发送小块数据是不被推荐的,因为TCP握手的开销增加了,并且头部受到了限制。 假设一个telnet连接 ,其中为每个发送的字符添加一个用于TCP和其他用于IP的报头(对于TCP 20个字节,对于IP是20个字节,对于以太网CRC是14个字节,以及对于以太网CRC是4个)最多为60字节+只传输一个字符。 通常,每个TCP段都被单独确认,这样就有一个完整的往返时间来发送一个段并得到确认(只是为了能够释放缓冲区资源并假设这个字符被传送)

那么,最后是什么限制? 这取决于你的应用程序。 如果你可以处理可用的内核资源,并且不需要更多的缓冲区,那么你可以在用户空间中传递没有缓冲区的缓冲区。 如果你需要更多的东西,你需要实现缓冲区,并且能够在你的缓冲区数据可用时提供内核缓冲区。