我有一个奇怪的问题,那就是select在Linux的套接字上花费了很多时间。
通常,数据传输确实非常快。但是:在客户端中进行选择以测试写操作是否会阻塞需要很长时间(发送数据而不在之前调用select的情况下:0.5s,在实际发送数据之前通过调用select来发送相同的数据:5s)。该问题特定于缓冲区大小。如果我将客户端中的发送缓冲区增加到4 * 4096,问题就消失了。
现在,我想知道为什么选择特定缓冲区大小需要这么长时间。示例代码在这里:http : //pastebin.com/PqisLnLU
相同的代码可以在Windows甚至Linux的Windows子系统上运行,而不会出现这些怪异的行为。
谢谢!
您会看到Nagle算法的效果,该算法用于以延迟为代价提高TCP吞吐量。
如果在不久的将来要写入更多数据,则写入操作相对较小,并且会被延迟,然后可以将这些数据打包到一个IP数据包中。当您select
在发送之前使用时,您不会发送更多信息(因为发送缓冲区仍已满),因此在发送数据包(并且清空缓冲区)之前会有明显的延迟。取而代之的是,您不使用select
缓冲区已满,因此当您使用更多缓冲区时,它会立即通过网络堆栈分流send
。
(我猜您正在同一台计算机上运行客户端和服务器程序,因此它们之间的“网络”连接实际上是回送接口,其MTU很高;否则,Nagle的算法可能不会成为问题这里)。
当您充分增加缓冲区大小时,在缓冲区填充期间的某个时间点会达到合适的IP数据包大小,并且数据会立即通过网络推送(并在确认收到后从发送缓冲区中清除)-因此没有延迟。
尝试禁用Nagle的算法(在客户端中):
#include <netinet/tcp.h>
...
value = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&value, sizeof(int)))
{
printf("\n Error : SetSockOpt TCP_NODELAY Failed \n");
}
您将看到,使用变体的select
速度与不进行任何select
操作的变体一样快。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句