2013-06-07 4 views
2

У меня возникла проблема с созданием действительно простого TCP-сервера для подключения к серверу с использованием boost asio. Когда я получаю соединение от клиента на моем сервере и попадаю в метод, обрабатывающий async_read_some, я проверяю наличие ошибки и всегда получаю ошибку 1236, которая дает сообщение «Сетевое соединение было прервано локальной системой».Boost asio «сетевое соединение было прервано локальной системой» на async_read_some

Я только начал работать с 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; 

Большая часть этого кода Prety много раз поднимается прямо из примеров на веб-сайте повышающего, так что я предполагаю, что я только что сделал что-то глупое где-то , но я просмотрел код несколько раз и не могу понять, где.

Любая помощь будет высоко оценена.

ответ

7

Срок службы ClientConnection заканчивается после handle_accepted_connection() выходов, потому что все экземпляры shared_ptr<ClientConnection> выходят из сферы действия и уничтожаются.

Чтобы избежать этой ситуации, вы можете использовать shared_from_this idiom в пределах ClientConnection функций-членов или сохранить 1 shared_ptr<ClientConnection> в некотором «диспетчере соединений».

+1

Извините, я бы включил код заголовка. Клиентское соединение действительно использует enable_shared_from_this, однако, снова просматривая это, кажется, что я привязываю свои методы обработки. Я все еще просто использовал «this» вместо «this-> shared_from_this()» У меня есть изменил его, и теперь он работает, поэтому я отвечу на ваш ответ. Большое спасибо. – Sam

+0

@Sam Да, «shared_from_this idiom» в этом контексте означает привязывание обработчиков к результату 'shared_from_this()', тем самым продлевая срок жизни объекта по крайней мере до тех пор, пока операция async не будет завершена. –

Смежные вопросы