2009-08-03 105 views
7

出於某種原因,這會導致訪問衝突,但沒有任何這詳細的文檔/幫助,我不知道在哪裏我做錯了。由於按照我在boost站點上看到的內容,這應該是正確的,並將每個asio :: write調用的內容從客戶端打印到新行。客戶似乎工作正常。雖然在服務器崩潰的時候,但它還沒有發送任何東西。的boost :: ASIO,異步讀取錯誤

訪問衝突發生在第275行的basic_stream_socket.hpp中。原因似乎是對象(boost :: asio :: stream_socket_service)未初始化(該指針的值爲0xfeeefeee),但我不知道不明白爲什麼它不是。

的程序輸出:

Start server
Server::startAccept()
Server::handleAccept()
Connection accepted
Connection::startRead()
Server::startAccept()
Connection::handleRead()
READ ERROR: The I/O operation has been aborted because either a thread exited or an application request
Connection::startRead()

代碼

#include "precompiled.h" 
#include "db.h" 
class Connection 
    : public boost::enable_shared_from_this<Connection> 
{ 
public: 
    typedef boost::shared_ptr<Connection> Pointer; 

    static Pointer create(boost::asio::io_service& ioService) 
    { 
     return Pointer(new Connection(ioService)); 
    } 

    ip::tcp::socket& getSocket() 
    { 
     return socket; 
    } 

    void startRead() 
    { 
     std::cout << "Connection::startRead()" << std::endl; 
     socket.async_read_some(boost::asio::buffer(readBuffer), 
      boost::bind(&Connection::handleRead,this,_1,_2)); 
    } 
private: 
    Connection(asio::io_service& ioService) 
     : socket(ioService) 
    { 
    } 

    void handleWrite(const boost::system::error_code&,size_t) 
    { 
    } 
    void handleRead(const boost::system::error_code&error,size_t len) 
    { 
     std::cout << "Connection::handleRead()" << std::endl; 
     if(error) 
     { 
      std::cout << "READ ERROR: "; 
      std::cout << boost::system::system_error(error).what(); 
      std::cout << std::endl; 
     } 
     else 
     { 
      std::cout << "read: "; 
      std::cout.write(readBuffer.data(),len); 
      std::cout << std::endl; 
     } 
     startRead(); 
    } 
    boost::array<char, 256> readBuffer; 
    ip::tcp::socket socket; 
}; 

class Server 
{ 
public: 
    Server(asio::io_service& ioService) 
     :acceptor(ioService, ip::tcp::endpoint(ip::tcp::v4(), getPort())) 
    { 
     startAccept(); 
    } 
private: 
    void startAccept() 
    { 
     std::cout << "RServer::startAccept()" << std::endl; 
     Connection::Pointer newConn = 
      Connection::create(acceptor.io_service()); 

     acceptor.async_accept(newConn->getSocket(), 
      boost::bind(&Server::handleAccept, this, newConn, 
      asio::placeholders::error)); 
    } 
    void handleAccept(Connection::Pointer newConn, 
     const boost::system::error_code& error) 
    { 
     std::cout << "Server::handleAccept()" << std::endl; 
     if(error) 
     { 
      std::cout << "CONNECTION ERROR: "; 
      std::cout << boost::system::system_error(error).what(); 
      std::cout << std::endl; 
     } 
     else 
     { 
      std::cout << "Connection accepted" << std::endl; 
      startAccept(); 
      newConn->startRead(); 
     } 
    } 
    ip::tcp::acceptor acceptor; 
}; 

int main() 
{ 
    std::cout << "Start server" << std::endl; 
    asio::io_service ioService; 
    RemoteAdminServer server(ioService); 
    boost::system::error_code error; 
    ioService.run(error); 
} 

回答

11

你應該改變這種代碼片段:

void startRead() 
    { 
     std::cout << "Connection::startRead()" << std::endl; 
     socket.async_read_some(boost::asio::buffer(readBuffer), 
           boost::bind(&Connection::handleRead,this,_1,_2)); 
    } 

到:

void startRead() 
{ 
    std::cout << "Connection::startRead()" << std::endl; 
    socket.async_read_some(boost::asio::buffer(readBuffer), 
       boost::bind(&Connection::handleRead,this->shared_from_this(),_1,_2)); 
} 

請注意,我通過了共享指針bind。這將保持你的Connection實例,直到處理程序被調用。否則,使用計數在Server::startAccept中變爲零,並且該對象被刪除。然後,當處理程序被調用時,內存無效,您會遇到可怕的「未定義行爲」。

0

我覺得你的存在跑,因爲你沒有留在工作隊列中的任何工作。

您必須防止退出和摧毀你的服務對象運行。

要麼試試這個:

boost::asio::io_service::work

或只是做一個

do { ioService.run(error); } while(!error); 
+0

無論如何它永遠不會退出run() – 2009-08-03 15:45:58

相關問題