Boost logo

Boost Users :

Subject: [Boost-users] io_service run thread exits on network disconnect (chat server example)
From: A.Agrawal_at_[hidden]
Date: 2010-02-26 00:41:10


Hello,

My code is similar to the one in chat_server example in boost
documentation. In my program I use boost asio to communicate with server.
Client has following code to connect to the server:

Class Members:
class DJClient
{
        tcp::socket *_socket;
        boost::asio::io_service io_service;
        boost::thread *t;
 
............................MORE...........................................
}

void DJClient::Connect() //To Connect to the server
{
  tcp::resolver resolver(io_service);
  tcp::resolver::query query("10.21.7.5", "50000");
  tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

  _socket = new tcp::socket(io_service);
  tcp::endpoint endpoint = *endpoint_iterator;

  _socket->async_connect(endpoint, boost::bind(&DJClient::handle_connect,
this,
                              boost::asio::placeholders::error,
++endpoint_iterator));
  t = new boost::thread(boost::bind(&boost::asio::io_service::run,
&io_service));
  return;
}

//Callback function after connection has been attempted, also reads data
asynchronously from the server
void DJClient::handle_connect(const boost::system::error_code& error,
                          tcp::resolver::iterator endpoint_iterator)
{
  if (!error)
  {
      boost::asio::async_read(*_socket,
boost::asio::buffer(_inbound_data_length),
              boost::bind(&DJClient::handle_read_data_length, this,
boost::asio::placeholders::error));
  }
  else if (endpoint_iterator != tcp::resolver::iterator())
  {
    _socket->close();
    tcp::endpoint endpoint = *endpoint_iterator;
    _socket->async_connect(endpoint,
boost::bind(&DJClient::handle_connect, this,
                              boost::asio::placeholders::error,
++endpoint_iterator));
  }
}

Client writes to the server using the following code, this happens in the
main thread (the one that called Connect), asynchronously
void DJClient::GetAllWIs(const char* oow_id)
{
  io_service.post(boost::bind(&DJClient::write_wis_for_oow_req, this,
oow_id));
}

void DJClient::write_wis_for_oow_req(const char* oow_id)
{
  boost::asio::async_write(*_socket, oow_id,
               boost::bind(&DJClient::handle_write, this,
boost::asio::placeholders::error));
}

Everything works fine without any problem until network cable is
unplugged. After network cable is unplugged, a call to GetAllWI does not
call write_wis_for_oow_req. I can see an exit thread message in Visual
Studio output window. I suspect that io_service::run exits and io_service
is no longer valid and that is why it does not call the method. My program
needs to handle this scenario and Client should be able to detect network
problem and reconnect.

1. It would be great help if someone can suggest a way to handle this
scenario. Is there a way to know this io_service::run has exited.
2. I can see in watch window that io_service._impl.stopped changes its
value from 0 to 1. But I do not know how to access it programmatically.

Any response will be greatly appreciated as I am not very experience in
using boost.

Thanks in advance

Anil Agrawal
Patrick Technology & Systems



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net