代理项目中的慢速套接字read()

时间:2013-02-17 13:07:23

标签: c++ sockets

我正在为学校项目编写一个http 1.0 Web代理。我已经完成了所有工作,但我的read()电话非常慢。我在read()调用(C的stdlib中的那个)周围放了一个计时器。我看到一堆0读取后跟一个需要5到20秒。这是在简单的高速网站(谷歌,debian等)。在杂乱的网站上,事情超时,页面永远不会加载(cnn,yahoo等)。

我正在从请求的Host:行向服务器打开一个套接字,并从代理浏览器(在本例中为firefox)写入确切的GET请求。写入需要0。这是一个示例请求(哈希用于可视化)。

#########
GET http://debian.org/ HTTP/1.0
Host: debian.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive


#########

(最后包括两条\r\n行。) 我读错了吗?或者我提出了错误的请求?在chrome中加载页面,甚至在telnet中使用GET请求都是快速的。

这是执行阅读的代码。 “实际读取时间”输出通常类似于0,0,...,0,15。

boost::shared_ptr<std::string> SocketBase::read(bool toEof) const
{
  if (!this->isConnected())
  {
    Exceptions::raise<std::runtime_error>(__FILE__, __LINE__, "Socket is not connected.");
  }

  boost::shared_ptr<std::string> bytes = boost::shared_ptr<std::string>(new std::string());
  while (toEof || bytes->rfind(CRLFCRLF) == std::string::npos)
  {
    char buffer[BufferSize];
    time_t before = ::time(0);
    int rc = ::read(this->socket, buffer, BufferSize);
    time_t after = ::time(0);
    std::cerr << "Actual read time: " << after - before << "s." << std::endl;

    if (rc == 0)
    {
      break;
    }
    else if (rc < 0)
    {
      Exceptions::raise<Exceptions::ReadException>(__FILE__, __LINE__, ::strerror(errno));
    }
    else
    {
      bytes->append(buffer, buffer + rc);
    }
  }

  return bytes;
}

1 个答案:

答案 0 :(得分:1)

您正在使用“Connection:keep-alive”行,它告诉服务器您希望在同一连接上有多个请求。服务器将发送响应并在那里闲置等待进一步的请求。如果没有连接,它最终会关闭连接。这可能就是你所看到的行为。如果您希望服务器在请求服务后关闭连接,请通过“连接:关闭”请求它执行此操作。对于保持活动连接(以及更高的性能),你真的应该使用HTTP / 1.1并使用Content-Length头...