async_read_until处理程序调用两次

时间:2013-04-12 18:30:08

标签: c++ boost-asio

我正在尝试使用boost asio库来实现网络编程。 以下是当某些数据(以“##”结尾)到达端点时调用的代码。

{
    boost::asio::async_read_until(m_socket, m_response,
                std::string("##"),
                boost::bind(&CTcpClient::HandleReceive,
                                shared_from_this(),
                                boost::asio::placeholders::error,
                                boost::asio::placeholders::bytes_transferred));

}


void CTcpClient::HandleReceive(const ErrorCodeType p_errorCode, size_t p_length)
{
    IN_FUNCTION

    if ( !p_errorCode )
    {
        logInfo(STR("Data received ..."));

        boost::asio::async_read_until(m_socket, m_response,
            std::string("##"),
            boost::bind(&CTcpClient::HandleReceive,
                            shared_from_this(),
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));

        m_onReceiveSignal(sbuf2s(m_response));

    }
    else
    {
        Shutdown(p_errorCode);
    }

    OUT_FUNCTION
}

假设发送到终点的数据是“KINGS ##”。因此,Handlereceive应该被调用一次。但是在我的代码中,这个被调用了两次,一次是“KINGS ##”,另一次是空字符串。

有人可以告诉我是什么原因以及如何解决它?

2 个答案:

答案 0 :(得分:1)

成功阅读后,您需要清除m_response缓冲区,直至令牌。

由于在重新发出异步读取之前没有这样做,因此响应缓冲区中仍然包含##个字符,因此读取将立即完成。

作为旁注,async_read_until调用可以读取超出##的数据,因此您必须小心,只清除并包括##,但不要过去它

答案 1 :(得分:0)

我认为你只需要在m_onReceiveSignal(...)之后调用async_read_until(...)。 改变Handlereceive内部的顺序。

这是假设第一次调用Handlereceive是来自另一种方法(可能是连接)通过async_read_untill(...)