C++ 当streambuf由以前的异步读取填充时,boost::asio::async_读入boost::asio::streambuf块

C++ 当streambuf由以前的异步读取填充时,boost::asio::async_读入boost::asio::streambuf块,c++,boost,boost-asio,C++,Boost,Boost Asio,我搜索了其他帖子,但没有找到任何相关内容。 现在,我有了一个由头和体组成的协议。 协议类似于: Z2491009802123456789ABCDEF 其中Z24是标题。Z是消息类型,24是要读取的剩余字节。剩余的字节是可变的,所以我一直读取,直到找到第一个“” void handle_handshake(const boost::system::error_code& error) { if (!error) { boost::asio::async_re

我搜索了其他帖子,但没有找到任何相关内容。 现在,我有了一个由头和体组成的协议。 协议类似于: Z2491009802123456789ABCDEF 其中Z24是标题。Z是消息类型,24是要读取的剩余字节。剩余的字节是可变的,所以我一直读取,直到找到第一个“”

void handle_handshake(const boost::system::error_code& error)
{
    if (!error)
    {
        boost::asio::async_read_until(
            socket_,
            inputStreamBuffer_,
            ',',
            boost::bind(
                &session::doReadHeader, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred)
        );
    }
    else
    {
        delete this;
    }
}

void doReadHeader(
    const boost::system::error_code& error,
    size_t bytes_transferred)
{
    if (!error)
    {
        istream is(&inputStreamBuffer_);
        vector<char> v(bytes_transferred);
        is.read(&(v[0]),bytes_transferred);
        request_.append(v.begin(),v.end());

        cout << "request_=#" << request_ << "#" << endl;
        int nBytes=string_to_llint(request_.substr(1,request_.size()-2));
        cout << "nBytes=" << nBytes << endl;
        cout << "size=" << inputStreamBuffer_.size() << endl;

        boost::asio::async_read(
            socket_,
            inputStreamBuffer_,
            boost::asio::transfer_at_least(nBytes),
            boost::bind(
                &session::doReadBody, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred)
        );
    }
    else
    {
        delete this;
    }
}

void doReadBody(
    const boost::system::error_code& error,
    size_t bytes_transferred)
{
    if (!error)
    {
        istream is(&inputStreamBuffer_);
        vector<char> v(bytes_transferred);
        is.read(&(v[0]),bytes_transferred);
        request_.append(v.begin(),v.end());

        string response=cardIssueProcessor_.process(request_);
        cout << "request=#" << request_ << "#" << endl;
        cout << "response=#" << response << "#" << endl;
        request_.clear();

        boost::asio::async_write(
            socket_,
            boost::asio::buffer(response, response.size()),
            boost::bind(
                &session::doWriteResponse, this,
                boost::asio::placeholders::error)
        );
    }
    else
    {
        delete this;
    }
}
void handle\u握手(const boost::system::error\u代码和错误)
{
如果(!错误)
{
boost::asio::异步读取(
插座,
输入流缓冲区,
',',
boost::bind(
&会话::doReadHeader,这个,
boost::asio::占位符::错误,
boost::asio::占位符::字节(已传输)
);
}
其他的
{
删除此项;
}
}
空头(
常量boost::system::error\u代码和错误,
大小(传输的字节数)
{
如果(!错误)
{
istream是(&inputStreamBuffer_);
向量v(传输的字节数);
is.read(&(v[0]),字节被传输;
请求附加(v.begin(),v.end());
cout表示async_read_until调用可能会将超出分隔符的数据读入缓冲区(请参阅备注部分)。也就是说,根据您的输入,检查缓冲区是否有更多数据的解决方案是一个很好的解决方案


正如我在上面的评论中提到的,如果您的需求允许您这样做,那么对剩余字节使用整数值而不是字符串可能会使您的工作更轻松,代码更干净,更不容易出错。

异步读取,直到
可以读取字节为止

评论 异步读取成功后,直到 操作时,streambuf可能包含 超出分隔符的其他数据。 应用程序通常会离开 在streambuf中为 后续异步读取直到操作 检查


在执行async_read()之前,我尝试检查缓冲区的填充情况对于正文。我有点工作。这是正确的解决方案吗?我不确定您的要求是否允许您这样做,但通常更容易使用定义字节大小的整数值来表示要读取的剩余字节,而不是可变长度的字符串。首先,感谢您的答复。这现在是有意义的。不过,我期望的是,这很简单nc_read_until()将返回从套接字实际读取的字节数,而不是返回在分隔字符之前的字节数。无论如何,我制定的解决方案似乎正在工作,但async_read()调用需要一些更改:
boost::asio::async_read(socket、inputStreamBuffer、boost::asio::transfer至少(toReadBytes)、boost::bind(&session::doReadBody、this、boost::asio::placeholders::error、nBytes))
boost::asio::placeholders::bytes_transfered实际上表示来自套接字的新字节,并且不包括以前使用async_read_进行的读取,直到。因此,我将实际字节计数传递给回调。不过,我仍在考虑将正文长度字段的大小设置为静态。谢谢。非常感谢。async_read_直到()很明显,所以我没有阅读全部文档。不只是“可以”,它很可能会。它尝试读取streambuf当前的可用容量,但最多65536。
void doReadHeader(
    const boost::system::error_code& error,
    size_t bytes_transferred)
{
    if (!error)
    {
        istream is(&inputStreamBuffer_);
        vector<char> v(bytes_transferred);
        is.read(&(v[0]),bytes_transferred);
        request_.assign(v.begin(),v.end());

        cout << "request_=#" << request_ << "#" << endl;
        int nBytes=string_to_llint(request_.substr(1,request_.size()-2));
        cout << "nBytes=" << nBytes << endl;
        cout << "size=" << inputStreamBuffer_.size() << endl;

        size_t toReadBytes=nBytes-inputStreamBuffer_.size();
        if (toReadBytes>0)
        {
            boost::asio::async_read(
                socket_,
                inputStreamBuffer_,
                boost::asio::transfer_at_least(toReadBytes),
                boost::bind(
                    &session::doReadBody, this,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred)
            );
        }
        else
        {
            doReadBody(error,nBytes);
        }
    }
    else
    {
        delete this;
    }
}