2009-08-03 40 views
7

Vì một số lý do dẫn đến vi phạm truy cập, tuy nhiên không có bất kỳ tài liệu/trợ giúp chi tiết nào về điều này, tôi không chắc mình đang làm sai ở đâu. Kể từ khi đi theo những gì tôi đã nhìn thấy trên trang web tăng này nên được chính xác, và in nội dung của mỗi asio :: ghi cuộc gọi từ khách hàng đến một dòng mới. Khách hàng dường như làm việc tốt. Mặc dù tại thời điểm máy chủ bị treo, nhưng nó vẫn chưa gửi bất kỳ thứ gì.boost :: asio, lỗi không đồng bộ đọc

Vi phạm truy cập xảy ra trong basic_stream_socket.hpp trên dòng 275. Nguyên nhân có vẻ là đối tượng (tăng :: asio :: stream_socket_service) không được khởi tạo (giá trị của con trỏ này là 0xfeeefeee), tuy nhiên tôi không 't thấy lý do tại sao nó không phải là.

Các chương trình đầu ra:

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); 
} 

Trả lời

11

Bạn nên thay đổi đoạn mã này:

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

tới:

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)); 
} 

Lưu ý rằng tôi đã chuyển một con trỏ được chia sẻ đến bind. Điều này sẽ giữ cho cá thể Connection của bạn xung quanh cho đến khi trình xử lý được gọi. Nếu không, số lượng sử dụng sẽ bằng 0 ở số Server::startAccept và đối tượng sẽ bị xóa. Sau đó, khi trình xử lý được gọi, bộ nhớ không hợp lệ và bạn trải nghiệm "hành vi không xác định" đáng sợ.

0

Tôi nghĩ rằng chạy của bạn tồn tại bởi vì bạn không có bất kỳ công việc còn lại trong hàng đợi công việc.

Bạn phải ngăn không cho chạy khỏi thoát và phá hủy đối tượng dịch vụ của mình.

Hoặc thử điều này:

boost::asio::io_service::work

hoặc chỉ làm một

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

Nó không bao giờ thoát() anyway –

+0

Bạn không thể chạy lại 'io_service' mà không cần đặt lại. –

Các vấn đề liên quan