異常な問題が発生しています。C++ Boost.ASIO Web サーバーがあり、着信要求を処理するために次のコードを使用しています。
boost::asio::async_read_until(
socket_,
response_,
"\r\n\r\n",
boost::bind(
&connection::handle_read_headers,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
(「socket_」はブースト::asio::ip::tcp::socket、「response_」はブースト::asio::streambuf)
私はリクエストのヘッダーを取得しようとしていますが、後でリクエストヘッダーから解析された「Content-Length」と一致する transfer_exactly を使用して 2 番目の async_read_until を実行します。問題は、上記のコードが非常に最新のサーバーに戻るのに 100 ~ 900 ミリ秒かかっていることです (その読み取りブロックから、handle_read_headers() が呼び出されるまで)。着信要求は次のようになります。
POST /load HTTP/1.1
host: www.mysite.com
Accept: */*
Accept-Encoding: gzip,deflate
Content-type: application/x-www-form-urlencoded
From: googlebot(at)googlebot.com
Origin: http://www.mysite.com
Referer: http://www.mysite.com/another-page/
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
X-Forwarded-For: 66.249.75.103
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Content-Length: 287
Connection: keep-alive
and-the-actual-content-is-here.... (287 bytes worth)
ヘッダーは \r\n\r\n で終了しているように見え、EOF まで読み取る前に handle_read_headers() 関数をトリガーします (ページ全体を読み取らないため) - 実際には正規表現をトリップしています。そして、これらのリクエストは Google から来ているので、遅れているわけではないと確信しています。
戻るのに時間がかかる理由について見落としているものはありますか? 私が見逃したかもしれない aync_read_until の他のキャッチはありますか?
ありがとう!
編集/更新: さて、私は非常に混乱しています。メガバイトの提案を試す際に、streambuf から文字配列に切り替えて (うまくいきませんでした)、コードをリファクタリングして async_read_until ではなく async_read_some を使用し、区切り記号を手動でスキャンしました。また、すべての OS 変数 (sysctrl.conf) をボーン ストックのデフォルトにリセットしました (可能性を絞り込むため)。残念ながら、次のコードでは、同じ受信 POST リクエストで handle_read() を呼び出しているため、まだ 100 ~ 900 ミリ秒の遅延が見られます。
socket_.async_read_some(
boost::asio::buffer(response_),
boost::bind(
&connection::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
ここで、response_ は次のようになります。
boost::array<char, 4096> response_;
役に立たない(同じ100〜900ミリ秒の遅延)。これが正常であるはずがありません - 何か考えはありますか?
EDIT2:Rhashimoto の推奨に従って、ハンドラーの追跡を有効にすると、ログに次の奇妙な点が見つかりました。
[2013-07-05 15:58:39 - Thread 7fae57e3f700]: Incoming connection (0ms elapsed)
@asio|1373054319.874916|506*508|socket@0x7fae50004f98.async_receive
@asio|1373054319.874963|506*509|socket@0x7fffd40fed68.async_accept
@asio|1373054319.875008|<506|
@asio|1373054320.609088|>508|ec=system:0,bytes_transferred=512
@asio|1373054320.609233|508*510|socket@0x7fae50004f98.async_receive
@asio|1373054320.609264|<508|
@asio|1373054320.609284|>510|ec=system:0,bytes_transferred=404
[2013-07-05 15:58:40 - Thread 7fae57e3f700]: Received packet headers (638 bytes) - 734ms elapsed
async_accept と async_receive の間には 700 ミリ秒以上あります。コードでは、このブロックから (事実上、 http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.htmlの「HTTP Server 2」から直接) - server. cpp および connection.cpp):
new_connection_->start();
new_connection_.reset(new connection(
io_service_pool_.get_io_service()
));
acceptor_.async_accept(
new_connection_->socket(),
boost::bind(
&server::handle_accept,
this,
boost::asio::placeholders::error
)
);
そして start() から:
void connection::start()
{
boost::asio::async_read_until(
socket_,
response_,
"\r\n\r\n",
boost::bind(
&connection::handle_read_headers,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
そして、handle_read_headers() が呼び出されると、700ms が経過します。
誰かアイデアはありますか?私は完全に迷っています。
本当にありがとう!