2009-08-03 15 views
7

किसी कारण से इसका परिणाम उल्लंघन उल्लंघन होता है, हालांकि इस पर कोई विस्तृत दस्तावेज़ीकरण/सहायता नहीं है, मुझे यकीन नहीं है कि मैं इसे गलत कहां कर रहा हूं। चूंकि मैंने बूस्ट साइट पर जो देखा है, उसके चलते यह सही होना चाहिए, और प्रत्येक एएसओ :: क्लाइंट से एक नई लाइन पर कॉल लिखना चाहिए। ग्राहक ठीक काम करता प्रतीत होता है। हालांकि बिंदु पर सर्वर दुर्घटनाग्रस्त हो जाता है, लेकिन उसने अभी तक कुछ भी नहीं भेजा है।boost :: asio, asynchronous read error

लाइन 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

यह कभी भी बाहर निकलता नहीं है() –

+0

आप इसे रीसेट किए बिना 'io_service' को फिर से चला नहीं सकते। –

संबंधित मुद्दे