【问题标题】:boost::asio, asynchronous read errorboost::asio,异步读取错误
【发布时间】:2009-08-03 15:18:31
【问题描述】:

由于某种原因,这会导致访问冲突,但是没有任何详细的文档/帮助我不确定我在哪里做错了。由于按照我在 boost 站点上看到的内容,这应该是正确的,并将客户端的每个 asio::write 调用的内容打印到新行。客户端似乎工作正常。虽然此时服务器崩溃了,但它还没有发送任何东西。

访问冲突发生在第 275 行的 basic_stream_socket.hpp 中。原因似乎是对象 (boost::asio::stream_socket_service) 未初始化(this 指针的值为 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);
}

【问题讨论】:

    标签: c++ boost boost-asio


    【解决方案1】:

    你应该修改这个代码sn-p:

       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 中的使用计数变为零,并且该对象被删除。然后,当调用处理程序时,内存无效,您会遇到可怕的“未定义行为”。

    【讨论】:

      【解决方案2】:

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

      您必须防止运行退出并破坏您的服务对象。

      要么试试这个:

      boost::asio::io_service::work

      或者只是做一个

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

      【讨论】:

      • 你不能重新运行io_service而不重置它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 2011-02-16
      • 1970-01-01
      • 2014-11-12
      相关资源
      最近更新 更多