在async_read_some上提升asio“网络连接被本地系统中止”

时间:2013-06-07 08:38:01

标签: c++ boost network-programming boost-asio

我在使用boost asio创建一个非常简单的基于TCP的服务器 - 客户端连接时出现问题。当我从我的服务器上的客户端获得连接并进入处理async_read_some的方法时,我检查错误,并且总是收到错误1236,这给出了消息"网络连接被本地系统中止"

我刚刚开始使用boost,所以我并不熟悉图书馆的运作方式以及我本可以做错的事情。我在下面提供了我的代码的简化版本:

/*Client connection code*/
ClientConnection::ClientConnection(boost::asio::io_service& io_service) : m_Socket(io_service)
{

}

ClientConnection::ClientConnectionPointer ClientConnection::Create(boost::asio::io_service& io_service)
{
    return ClientConnection::ClientConnectionPointer(new ClientConnection(io_service));
}

void ClientConnection::handle_write(const boost::system::error_code& error, size_t bytes_transferred)
{
    //once we've written our packet, just wait for more
    m_Socket.async_read_some(boost::asio::buffer(m_IncomingBytesBuffer, MAX_BYTES_LENGTH),
        boost::bind(&ClientConnection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void ClientConnection::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
    if(!error)
    {
        //deal with the data that comes in here

    }
    else
    {
        std::cout << "Error reading port data" << std::endl;
        std::cout <<  error.message() << std::endl;
    }

}

tcp::socket& ClientConnection::GetSocket(void)
{
    return m_Socket;
}

void ClientConnection::RunClient(void)
{
    std::cout << "Client connected." << std::endl;
    //start by reading data from the connection
    m_Socket.async_read_some(boost::asio::buffer(m_IncomingBytesBuffer, MAX_BYTES_LENGTH),
        boost::bind(&ClientConnection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}



/*Listener server code here*/
BarcodeServer::BarcodeServer(boost::asio::io_service& io_service) : m_acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT_NUMBER))
{
    start_accepting_connections();
}

void BarcodeServer::start_accepting_connections(void)
{
    std::cout << "Waiting for a connection." << std::endl;
    ClientConnection::ClientConnectionPointer new_connection = ClientConnection::Create(m_acceptor.get_io_service());

    m_acceptor.async_accept(new_connection->GetSocket(), boost::bind(&BarcodeServer::handle_accepted_connection, this, new_connection, boost::asio::placeholders::error));
}

void BarcodeServer::handle_accepted_connection(ClientConnection::ClientConnectionPointer new_connection, const boost::system::error_code& error)
{
    if(!error)
    {
        new_connection->RunClient();
    }
    start_accepting_connections();
}


/*main code here*/
try
{
    boost::asio::io_service io_service;
    BarcodeServer server(io_service);
    io_service.run();
}
catch(std::exception& e)
{
    cout << "Error when running server:" << endl;
    cout << e.what() << endl;
    return RETURN_CODE_SERVER_RUN_ERROR;
}
return RETURN_CODE_SUCCESS;

这些代码中的大多数都是直接从boost网站上的示例中提取的,所以我猜测我在某个地方做了些傻事,但我已经查看了一些代码时间,无法弄清楚在哪里。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:8)

ClientConnection退出后handle_accepted_connection()的生命周期结束,因为shared_ptr<ClientConnection>的所有实例都超出范围并被销毁。

要避免这种情况,您可以在shared_from_this成员函数中使用ClientConnection惯用法,也可以在某个“连接管理器”中存储1 shared_ptr<ClientConnection>