Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost asio : how to keep a client connection alive?

I try to create a client who keep the connection alive on the server.

However, when i receive data once, the connection was closed. I don't understand why.

I think that i should make a loop, but we told me that wasn't a good idea.

class client
{
public:
  client(boost::asio::io_service& io_service,
      const std::string& host, const std::string& service)
    : connection_(io_service)
  {
    // Resolve the host name into an IP address.
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(host, service);
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator =
      resolver.resolve(query);
    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;

    // Start an asynchronous connect operation.
    connection_.socket().async_connect(endpoint,
        boost::bind(&client::handle_connect, this,
          boost::asio::placeholders::error, ++endpoint_iterator));
  }

  /// Handle completion of a connect operation.
  void handle_connect(const boost::system::error_code& e,
      boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
  {
    if (!e)
    {
      // Successfully established connection. Start operation to read the list
      // of stocks. The connection::async_read() function will automatically
      // decode the data that is read from the underlying socket.
      connection_.async_read(stocks_,
          boost::bind(&client::handle_read, this,
            boost::asio::placeholders::error));
    }
    else
    {
      std::cerr << e.message() << std::endl;
    }
  }

  /// Handle completion of a read operation.
  void handle_read(const boost::system::error_code& e)
  {
    if (!e)
    {
      // Print out the data that was received.
      for (std::size_t i = 0; i < stocks_.size(); ++i)
      {
        std::cout << "Paquet numero " << i << "\n";
        std::cout << "  age: " << stocks_[i].age << "\n";
        std::cout << "  name: " << stocks_[i].nom << "\n";
      }

                // Maybe Should i put something here ?
    }
    else
    {
      // An error occurred.
        std::cerr << "Error : " << e.message() << std::endl;
        connection_.socket().close();
    }

    // or maybe here ?

  }

private:
  /// The connection to the server.
  connection            connection_;
  std::vector<stock>    stocks_;
};

the main looks like this :

int main(int argc, char* argv[])
{
  try
  {
    // Check command line arguments.
    if (argc != 3)
    {
      std::cerr << "Usage: client <host> <port>" << std::endl;
      return 1;
    }

    boost::asio::io_service io_service;

    client client(io_service, argv[1], argv[2]);
    io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
like image 748
user377158 Avatar asked Nov 28 '10 18:11

user377158


1 Answers

Your asio io_service is running out of work to do. In handle_read, where you put your comment, "Maybe should I put something here", you could schedule the next async read operation:

connection_.async_read(stocks_,
      boost::bind(&client::handle_read, this,
        boost::asio::placeholders::error));

Typically, if you're programming asynchronously, once an async handler is called, you will call the next async operation, just like you did in the async connect handler.

like image 152
Ralf Avatar answered Oct 02 '22 20:10

Ralf