$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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