Boost logo

Boost Users :

From: Simon Pickles (sipickles_at_[hidden])
Date: 2008-07-27 09:34:18


Hello,

I am having a little trouble getting my boost::ASIO TCP client to actually
re-attempt a connected if the first attempt failed. With my server
offline, the call to async_connect correctly times out. When I try the
async_connect call a second time, it doesn't time out.

I am running my io_service listener in a boost thread, and am not
changing this between async_connect calls. However, my debugger
(MSVC2005, boost 1.35) does show a thread exit at this time. I don't
think its the relevant thread (at the second call to connect there is an
extra thread running (the io_service I guess).

Here's my two relevant files. Thanks very much for any pointers

Simon

// Network.cpp
//--------------------
// CNetwork::Connect
   
    // ........
    m_client = boost::shared_ptr<CASIOClient>( new CASIOClient( m_log,
                                                                m_initXML,
                                                                m_IO,
                                                                this ) );

        try
        {
            tcp::resolver resolver(*(m_IO.get()));
            tcp::resolver::query query( m_serverHost.c_str(),
m_serverPort.c_str() );
            tcp::resolver::iterator iterator = resolver.resolve(query);

            m_client->Connect(iterator);
            m_log->NET( "Looking for Server at %s:%s\n",
m_serverHost.c_str(), m_serverPort.c_str() );
        }
        catch (boost::system::error_code& e)
        {
            m_log->NET("%s\n", e.message().c_str() );
            m_log->NET("Server not found?\n");
            return -1;
        }
        catch (std::exception& e)
        {
            m_log->NET("Exception %s\n", e.what() );
            return false;
        }

        // start the io service to listen for async ops
        if ( !m_listener )
            m_listener = boost::shared_ptr<boost::thread>( new
boost::thread(boost::bind(&boost::asio::io_service::run, m_IO.get()) ) );

//-------------------------------------
// CASIOClient.cpp
CASIOClient::CASIOClient( boost::shared_ptr<ILogInterface> log,
                            boost::shared_ptr<IXMLInterface> xml,
                            boost::shared_ptr<boost::asio::io_service> io,
                            CNetwork* network ): m_IO(io),
                                                    m_socket(*(io.get())),
                                                    m_network(network)
{
    m_log = log;
    m_initXML = xml;
}

void CASIOClient::Connect( tcp::resolver::iterator endpoint_iterator )
{
    tcp::endpoint endpoint = *endpoint_iterator;
    m_socket.async_connect( endpoint,
                            boost::bind( &CASIOClient::HandleConnect,
                                            this,
                                            
boost::asio::placeholders::error,
                                            ++endpoint_iterator));

    m_connectionState = NETWORK_DISCONNECTED;
}

void CASIOClient::Close()
{
    m_log->NET("Starting Close...\n");
    m_IO->post(boost::bind(&CASIOClient::DoClose, this));
}

//////////////////////////////////////////
void CASIOClient::HandleConnect( const boost::system::error_code& error,
                                tcp::resolver::iterator endpoint_iterator)
{
    if (!error)
    {
        m_log->NET("Connected: %s\n", error.message().c_str());
        m_connectionState = NETWORK_CONNECTED;

       boost::asio::async_read_until( m_socket,
                                        m_rx,
                                        '@', // termination char
                                        boost::bind(
&CASIOClient::HandleReadUntil,
                                                        this,
                                                        
boost::asio::placeholders::error));
    }
    else if (endpoint_iterator != tcp::resolver::iterator())
    {
        m_log->NET("Connection unsuccessful: %s\n",
error.message().c_str());
        m_log->NET("Retrying\n");

        tcp::endpoint endpoint = *endpoint_iterator;
        m_socket.async_connect( endpoint,
                                boost::bind( &CASIOClient::HandleConnect,
                                                this,
                                                
boost::asio::placeholders::error, ++endpoint_iterator));
    }
    else
    {
        m_log->NET("Connect Error: %s\n", error.message().c_str());

        DoClose();
    }

}

void CASIOClient::HandleReadUntil(const boost::system::error_code& error)
{
    if (!error)
    {
        std::istreambuf_iterator<char> iter(&m_rx);
        std::istreambuf_iterator<char> end;
        std::string read(iter, end);

        std::string clipMsg;
        while (read.length())
        {
            int n = read.find("@");
            clipMsg = read.substr( 0, n );
            m_log->NET( "Message received: %s\n", clipMsg.c_str() );

           m_network->QueueReceivedMessage( clipMsg );

            read = read.substr( n+1, read.length()-n-1 );

        }

        // start listening again
        boost::asio::async_read_until( m_socket,
                                        m_rx,
                                        '@',
                                        boost::bind(
&CASIOClient::HandleReadUntil,
                                                        this,
                                                        
boost::asio::placeholders::error));
    }
    else
    {
        m_log->NET( "ReadUntil Error: %s\n", error.message().c_str() );
        DoClose();
    }
}

void CASIOClient::DoClose()
{
    m_log->NET( "Closing ASIO\n" );
    m_socket.close();

    m_connectionState = NETWORK_FAILED;

}


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