Frage

Aus irgendeinem Grund dies zu einer Zugriffsverletzung führt, jedoch keine detaillierte Dokumentation / Hilfe, auf das ich nicht sicher bin, wo ich es falsch mache. Da geht von dem, was ich auf der Boost-Website gesehen haben sollte dies korrekt sein, und drucken Sie den Inhalt jeden asio :: Schreibaufruf vom Client auf eine neue Zeile. Der Kunde scheint gut zu funktionieren. an dem Punkt, obwohl der Server abstürzt, aber es hat noch nicht gesendet hat.

Die Zugriffsverletzung tritt in basic_stream_socket.hpp auf Linie 275. Die Ursache scheint zu sein, dass das Objekt (boost :: asio :: stream_socket_service) nicht initialisiert (den Wert des dieser Zeiger ist 0xfeeefeee), aber ich don‘ t sehen, warum es nicht ist.

Die Programme Ausgabe:

  

Server Euro Start   Server :: startAccept ()
  Server :: handleAccept ()
  Verbindung angenommen
  Connection :: Starte ()
  Server :: startAccept ()
  Connection :: handleRead ()
  READ ERROR: Die I / O-Operation abgebrochen wurde, weil entweder ein Faden oder eine Anwendungsanforderung beendet
  Connection :: Startet ()

Der Code

#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);
}
War es hilfreich?

Lösung

Sie sollten diesen Code-Schnipsel ändern:

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

zu:

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

Beachten Sie, dass ich bestehen a shared pointer bind. Dies hält die Connection Instanz herum, bis der Handler aufgerufen wird. Andernfalls geht der Einsatz auf Null zurück in Server::startAccept und das Objekt gelöscht wird. Dann, wenn der Handler aufgerufen wird, der Speicher ist ungültig und erleben Sie das gefürchtete „nicht definiertes Verhalten.“

Andere Tipps

Ich denke, Ihr Lauf existiert, weil Sie keine Arbeit in der Warteschlange links verfügen.

Sie müssen den Lauf verhindern, Verlassen und Ihr Service-Objekt zu zerstören.

Entweder versuchen Sie dies:

boost :: asio :: io_service :: Arbeit

oder einfach ein

do { ioService.run( error ); } while( !error );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top