1

Boost.Asio Example HTTP Server 2 (io_service-per-CPU 設計を使用)に基づく http サーバーがあります。

各リクエストは解析され、それが POST リクエストかどうか、Path が正しいかどうか、Content-Length ヘッダーが存在するかどうかがチェックされ、これらの条件のいずれかが正しくない場合は、Bad-Request Response が生成されます。

すべて問題ないので、OK 応答を送信します。

それが始まりです。

int main(int argc, char* argv[])
{
  try
  {
    http::server s("127.0.0.1", "88", 1024);
    s.run();
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  return 0;
}

ここで、16 個のスレッドを開始し、各スレッドが while(true)-Loop POST-Requests でこのサーバーに継続的に送信する簡単な C# アプリを作成しました。

しばらくの間、スムーズかつ高速に実行されます。その後、ある時点でサーバーが応答しなくなります (リモート サーバーに接続できません)。

この原因として、サーバーからのセッションが適切に閉じられていないことが考えられます。

Bad-Request/OK Responses のコードは次のとおりです。

void session::handle_request()
{
  //Generate OK Response
  reply_ = reply::stock_reply(reply::ok);
  //Send OK Response
  boost::asio::async_write(client_socket_, reply_.to_buffers(), 
    boost::bind(&session::handle_client_write, shared_from_this(),
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
}

void session::send_bad_request()
{
  //Generate Bad Request Response
  reply_ = reply::stock_reply(reply::bad_request);
  //Send Bad Request Response
  boost::asio::async_write(client_socket_, reply_.to_buffers(), 
    boost::bind(&session::handle_client_write, shared_from_this(),
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
}

そして、両方がトリガーする handle_client_write:

void session::handle_client_write(const boost::system::error_code& err, size_t len)
{
  if (!err) {
    //Dummy Error Code Var
    boost::system::error_code ignored_ec;
    //Shutdown socket
    client_socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
    client_socket_.close();
    //std::cout << "Closed" << ignored_ec.message() << "\n";
  }
  else {
    std::cout << "Error: " << err.message() << "\n";
  }
}

私が言ったように、ある時点で応答しなくなり、しばらくすると再び応答します。

4

0 に答える 0