1

学校のプロジェクト用に http 1.0 Web プロキシを作成しています。すべてが完了し、機能していますが、read()通話が非常に遅いです。呼び出しの周りにタイマーを配置しましたread()(Cのstdlibからのもの)。一連の 0 の読み取りの後に、5 ~ 20 秒かかる読み取りが続きます。これは単純な高速サイト (google、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


#########

(最後の2行も含めて\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;
}
4

1 に答える 1

1

「接続:キープアライブ」行を使用しています。これは、同じ接続で複数のリクエストを潜在的に持つ必要があることをサーバーに伝えます。サーバーは応答を送信し、アイドル状態で待機して次の要求を待ちます。接続が得られない場合は、最終的に接続を閉じます。これはおそらくあなたが見ている動作です。リクエストが処理された後にサーバーが接続を閉じるようにしたい場合は、"Connection: close" でそうするようにサーバーに依頼してください。キープアライブ接続 (およびより高いパフォーマンス) のためには、HTTP/1.1 を使用し、Content-Length ヘッダーを使用する必要があります...

于 2013-02-17T15:36:36.500 に答える