C填补了空缺的Linux笔记本电脑的神秘速度

时间:2018-10-10 16:49:29

标签: c performance sockets

我用C编写了一个简单的回显服务器(来自http://gnosis.cx/publish/programming/sockets.html),并且在localhost上一切正常。然后,我决定尝试以10,000个“客户端”匹配的紧密循环连接到服务器。它立即声称我打开了太多文件而失败。因此,我将其扩展到1022并开始工作(建立1022个连接,发送和接收数据)。我还发现我可以覆盖上限(在非特权模式下为4094,在特权模式下为1M吗?),该上限也可以使用。我当时感觉还不错,但是在从事select()epoll()之类的工作之前,我决定对非特权运行进行压力测试。我可以在大约0.5秒内连接并发送4000次(避免了4096次)(没有printf()记录)。我可以在几乎相同的时间连续执行三次。第四次大约需要6.0秒。然后我得到大约11.0秒的时间。相同的客户端程序(发送4000个5个字母的单词)不变的服务器程序(MAXPENDING的值只有5个)...经过大约3或4次运行,我等待11.2097秒,然后又回到了0.5秒(三个),然后是6秒,然后又是11秒。 -感觉就像我用完了某种池子(大约12或13,000?),然后需要将其收集起来……缓慢地……我很乐意做些不同的事情,但我不知道是什么问题或解决方案。我还将服务器移到具有自己IP addr的VM,结果完全相同。谁能告诉我幕后情况以及最佳实践是什么?

我认为setsockopt(TCP_NODELAY)可能会抑制Nagle算法,但是结果是相同的:.5,.5,.5、6、11、11、11 如果我尽可能快地重复执行,它将使服务器暂时“崩溃”几秒钟。但是最终(“崩溃”或没有“崩溃”),我们在0.5秒内又返回了业务往返4000个“回声”。

在64位Ubuntu 18.04上运行gcc ... gcc -v给我:

Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 


for(i=0; i<CLIENT; i++)
{
    if (connect(sock[i], (struct sockaddr *) &echoserver[i], sizeof(echoserver[i])) < 0) Die("Failed to connect with server");

    echolen = strlen(argv[2]);
    if (send(sock[i], argv[2], echolen, 0) != echolen) Die("!");

    while (received < echolen) {
      int bytes = 0;
      if ((bytes = recv(sock[i], buffer[i], BUFFSIZE-1, 0)) < 1) Die("!rcv");
      received += bytes;
      buffer[i][bytes] = '\0';
    }
    close(sock[i]);
}

1 个答案:

答案 0 :(得分:0)

Netstat赢得了胜利。感谢评论员杰里米·弗里斯纳。问题在于套接字在TIME_WAIT状态下保持打开状态。当然,我将继续尝试解决这一问题。 TIME_WAIT似乎是不可避免的。如果是这样,我希望能够将系统的MAX_OPEN设置为大于16384的值。对此表示欢迎。如果我解决了,我会自己评论。 TIME_WAIT在我的笔记本电脑上持续60秒。我怎么知道date; netstat | wc ...老实说,我从不喜欢netstat,netcat,nc或其他会散发大量信息的systools。但这真是愚蠢的,开悟了我。 netstat很好。也要感谢其他评论员,他们也向正确的方向推动了我。谢谢,一个叫tad的人...谢谢,随便......