문제

어떤 이유로 든 이로 인해 액세스 위반이 발생하지만 이에 대한 자세한 문서/도움말이 없습니다. 내가 어디에서 잘못하고 있는지 잘 모르겠습니다. 부스트 사이트에서 본 것에 따라 이것은 정확해야하며, 각 ASIO :: 클라이언트에서 새 라인으로의 통화를 작성합니다. 클라이언트는 잘 작동하는 것 같습니다. 시점에서 서버는 충돌하지만 아직 아무것도 보내지 않았습니다.

액세스 위반은 275 행의 Basic_stream_Socket.hpp에서 발생합니다. 원인은 객체 (boost :: asio :: stream_socket_service)가 초기화되지 않은 것 같습니다 (이 포인터의 값은 0xfeeefeee입니다). 그렇지 않습니다.

프로그램 출력 :

서버를 시작하십시오
서버 :: startAccept ()
서버 :: HandleAccept ()
연결이 허용됩니다
연결 :: Startread ()
서버 :: startAccept ()
연결 :: handleread ()
오류 읽기 : 스레드가 종료되거나 응용 프로그램 요청이므로 I/O 작업이 중단되었습니다.
연결 :: 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);
}
도움이 되었습니까?

해결책

이 코드 스 니펫을 변경해야합니다.

   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 핸들러가 호출 될 때까지 주변 인스턴스. 그렇지 않으면 사용 카운트가 0으로 이동합니다 Server::startAccept 그리고 객체가 삭제됩니다. 그런 다음 핸들러가 호출되면 메모리가 유효하지 않으며 끔찍한 "정의되지 않은 행동"을 경험합니다.

다른 팁

작업 대기열에 작업이 남아 있지 않기 때문에 실행이 존재한다고 생각합니다.

실행이 서비스 객체를 종료하고 파괴하는 것을 방지해야합니다.

이것을 시도하십시오 :

부스트 :: asio :: io_service :: Work

아니면 그냥하십시오

do { ioService.run( error ); } while( !error );
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top