単純なTCPサーバーの実装に問題があります。次のコードは、boost :: asioの例、正確には「HttpServer1」から抜粋したものです。
void connection::start() {
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(
&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) {
if (!e && bytes_transferred) {
std::cout << " " << bytes_transferred <<"b" << std::endl;
data_.append(buffer_.data(), buffer_.data()+bytes_transferred);
//(1) what here?
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(
&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
else// if (e != boost::asio::error::operation_aborted)
{
std::cout << data_ << std::endl;
connection_manager_.stop(shared_from_this());
}
}
元のコードでbuffer_
は、はリクエスト全体を保持するのに十分な大きさです。それは私が必要なものではありません。サイズを32バイトに変更しました。
サーバーはローカルホストのポート80でコンパイルしてリッスンするので、Webブラウザーを介してサーバーに接続しようとします。
ここで、ステートメント(1)がコメント化されている場合、要求の最初の32バイトのみが読み取られ、接続がハングします。Webブラウザは応答を待ち続けます、サーバーはそうします..私は何を知りません。
(1)がコメント化されていない場合、リクエスト全体が読み取られます(そして、appedされますdata_
)が、停止することはありません-ブラウザでリクエストをキャンセルする必要があり、その後、else { }
部分が実行されます-stdoutにリクエストが表示されます。
質問1:大きなリクエストをどのように処理する必要がありますか?
質問2:リクエストをどのようにキャッシュする必要がありますか(現在、バッファを文字列に追加しています)?
質問3:リクエストが終了したことをどのように確認できますか?HTTPには常に応答があるので、Webブラウザーはそれを待ち続け、接続を閉じませんが、サーバーは要求が終了したことをどのように知ることができますか(おそらく、要求を閉じるか、「200OK」と応答します)。