【问题标题】:Boost Asio async_read doesn't stop reading?Boost Asio async_read 不会停止阅读?
【发布时间】:2010-12-10 23:46:06
【问题描述】:

所以,

我一直在使用 Boost asio 函数和套接字(特别是异步读/写)。现在,我认为boost::asio::async_read 仅在从网络连接进入新缓冲区时才调用处理程序......但是它不会停止读取相同的缓冲区并因此继续调用处理程序。我已经能够通过检查传输的字节数来缓解它,但是它基本上处于一个忙碌的等待循环中,浪费了 CPU 周期。

这是我所拥有的:

class tcp_connection : : public boost::enable_shared_from_this<tcp_connection> 
{
public:
    // other functions here

    void start()
    {
    boost::asio::async_read(socket_, boost::asio::buffer(buf, TERRAINPACKETSIZE),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
    }

private:
    const unsigned int TERRAINPACKETSIZE = 128;
    char buf[TERRAINPACKETSIZE];


    void handle_read(const boost::system::error_code& error, size_t bytesT)
    {
        if (bytesT > 0)
        { 
             // Do the packet handling stuff here
        }

        boost::asio::async_read(socket_, boost::asio::buffer(buf, TERRAINPACKETSIZE),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
    }
};

有些东西被删掉了,但基本上会创建一个新的连接,然后调用start()。有什么我遗漏的东西,所以handle_read 方法不会被连续调用吗?

【问题讨论】:

  • 你能告诉我们“buf”是如何初始化的吗(以及什么是TERRAINPACKETSIZE)?我问是因为我想知道您是否会遇到与以下讨论的情况相同的情况:lists.boost.org/boost-users/2009/06/49370.php
  • Eric,buf 是一个字符数组,TERRAINPACKETSIZE 是一个保存缓冲区大小的常量
  • 对不起,我几乎没有想法可以帮助你:(我从 asio 文档中获取了“异步 echo tcp 服务器”示例并对其进行了修改,使其会话与你在这里展示的那个(加上检查!handle_read 中的错误),它工作正常。我在 Windows 上试过;你在什么平台上运行这个?
  • 别担心人:)。我在 Windows 上运行它,我发现如果你调用 async_write 然后再次调用 async_read 它不会进入循环。

标签: c++ boost asynchronous boost-asio


【解决方案1】:

一个疯狂的猜测:你在handle_read 中检查error 吗?如果套接字由于某种原因处于错误状态,我猜从handle_readasync_read 的嵌套调用将立即“完成”,从而立即调用handle_read

【讨论】:

  • 如果没有错误条件(如果 (!error) ...),您应该只安排另一个 async_read。
【解决方案2】:

我遇到了同样的问题。就我而言,我正在读到这样的 std::vector

boost::asio::async_read(socket_,
st::asio::buffer(*message,message->size()),
            boost::bind(
              &ActiveSocketServerSession::handleFixLengthRead,
              shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)
    );

我有一个自适应向量来接受不同的字节数

    std::vector<unsigned char>* message;
message = new std::vector<unsigned char> (sizePacket);

当我收到第一个数据包时一切都很好,但在第一个数据包之后,永远不会停止在没有数据的情况下解锁 handle_reader。

我的解决方案是删除我的向量并在处理后再次分配空间:

void ActiveSocketServerSession::handleFixLengthRead(    const         boost::system::error_code& error,
                                                    std::size_t bytes_transferred){

    --> processing your data (save to another site)
--> delete message;
--> message = new std::vector<unsigned char> (sizePacket);

//starting to read again
boost::asio::async_read(socket_,
                boost::asio::buffer(*message,message->size()),
            boost::bind(
              &ActiveSocketServerSession::handleFixLengthRead,
              shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)
);

    }else{
        logMessage.str("");
        logMessage << "Error handling data id: "<<getId()<< "from port";
    }
}

把这两行放好之后就一切正常了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多