boost::asio,异步读取错误

7
由于某些原因,这会导致访问冲突,但是由于我没有关于此的详细文档/帮助,所以不确定我做错了什么。从我在boost网站上看到的内容来看,这应该是正确的,并且将每个asio::write调用从客户端打印到新行的内容。客户端似乎工作正常。尽管服务器崩溃了,但它还没有发送任何内容。
在basic_stream_socket.hpp的第275行发生了访问违规。原因似乎是对象(boost::asio::stream_socket_service)未初始化(this指针的值为0xfeeefeee),但我不知道为什么它没有被初始化。
程序输出如下:
开始服务器 Server::startAccept() Server::handleAccept() 连接已接受 Connection::startRead() Server::startAccept() Connection::handleRead() 读取错误:I/O操作已中止,因为线程退出或应用程序请求 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);
}
2个回答

11

您应该修改此代码片段:

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

请注意,我将一个shared pointer传递给bind。这将保持您的Connection实例在处理程序被调用时保持活动状态。否则,在Server::startAccept中,use count降至0,对象将被删除。然后,当处理程序被调用时,内存无效,您将经历可怕的“未定义行为”。


-1

我认为你的运行存在是因为工作队列中没有剩余任务。

你必须防止运行退出并销毁你的服务对象。

可以尝试这个:

boost::asio::io_service::work

或者只需执行:

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

您不能在不重置它的情况下重新运行 io_service - Igor R.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接