2

我在使用 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 网站上的示例中提取出来的,所以我猜我只是在某个地方做了一些愚蠢的事情,但是我已经查看了几次代码,但不知道在哪里。

任何帮助将非常感激。

4

1 回答 1

8

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

为避免这种情况,您可以在成员函数中使用shared_from_thisidiom或将 1 存储在某个“连接管理器”中。ClientConnectionshared_ptr<ClientConnection>

于 2013-06-07T09:05:13.440 回答