C++ 如何阅读Boost ASIO streambuf?

C++ 如何阅读Boost ASIO streambuf?,c++,boost,boost-asio,streambuf,C++,Boost,Boost Asio,Streambuf,有没有一种方法可以在不删除字节的情况下读取streambuf 我正在从缓冲区读取一个“消息大小”字段,以检查是否收到了整个消息 如果没有,我将发布另一个异步读取来获取它,但是处理程序无法知道消息应该有多长,因为size字段已被删除 感谢您的帮助 例如 您可以采用两种方法: 发出单个读取以读取大小的字节数(例如4),发出所需大小的读取 使用readsome调用,缓冲代码中的字节,比如向量,并以这种方式进行分析 我会选择选项2,它确实意味着复制缓冲区,但是我会冒险说它比多次读取调用便宜。您可以使用r

有没有一种方法可以在不删除字节的情况下读取streambuf

我正在从缓冲区读取一个“消息大小”字段,以检查是否收到了整个消息

如果没有,我将发布另一个异步读取来获取它,但是处理程序无法知道消息应该有多长,因为size字段已被删除

感谢您的帮助

例如


您可以采用两种方法:

  • 发出单个读取以读取大小的字节数(例如4),发出所需大小的读取

  • 使用readsome调用,缓冲代码中的字节,比如向量,并以这种方式进行分析


  • 我会选择选项2,它确实意味着复制缓冲区,但是我会冒险说它比多次读取调用便宜。

    您可以使用read\u async使用消息头的大小启动读取,然后在“完成条件”回调中调整它,如下所示:

    typedef boost::system::error_code error_code;
    
    template <typename Stream, typename Message>
    void MessageReader<Stream, Message>::startRead()
    {
      readBuffer = allocateMsg();
      async_read(stream, 
                 boost::asio::buffer(readBuffer.get(), sizeof(*readBuffer)),
                 boost::bind(&MessageReader<Stream, Message>::bytesToRead, this,
                             boost::asio::placeholders::error, 
                             boost::asio::placeholders::bytes_transferred),
                 boost::bind(&MessageReader<Stream, Message>::readDone, this, 
                             boost::asio::placeholders::error, 
                             boost::asio::placeholders::bytes_transferred));
    }
    
    template <typename Stream, typename Message>
    size_t MessageReader<Stream, Message>::bytesToRead(const error_code& error, 
                                                       size_t bytes_read)
    {
      size_t result;
    
      if (error)
        result = 0;                                         // error - stop reading
    
      else if (bytes_read < sizeof(CmnMessageHeader))
        result = sizeof(CmnMessageHeader) - bytes_read;     // read rest of header
    
      else if (readBuffer->header.byteCount > sizeof(*readBuffer))
        result = 0;                                         // bad byte count
    
      else
        result = readBuffer->header.byteCount - bytes_read; // read message body
    
      return result;
    }
    
    template <typename Stream, typename Message>
    void MessageReader<Stream, Message>::readDone(const error_code& error, 
                                                  size_t bytes_read)
    {
      if (error)
      {
        if (error.value() == boost::system::errc::no_such_file_or_directory)
        {
          notifyStop();
        }
    
        else if (error.value() != boost::system::errc::operation_canceled)
        {
          notifyStop();
        }
    
        // else the operation was cancelled, thus no stop notification is needed and
        // we can merely return
      }
    
      else if (bytes_read != readBuffer->header.byteCount)
      {
        LOG4CXX_ERROR(logger, "Message byte count mismatch");
        notifyStop();
      }
    
      else
      {
        handleMsg(readBuffer);
        startRead();
      }
    }
    
    typedef boost::system::error\u code error\u code;
    模板
    void MessageReader::startRead()
    {
    readBuffer=allocateMsg();
    异步读取(流,
    boost::asio::buffer(readBuffer.get(),sizeof(*readBuffer)),
    boost::bind(&MessageReader::bytesToRead),这个,
    boost::asio::占位符::错误,
    boost::asio::占位符::字节数,
    boost::bind(&MessageReader::readDone),这个,
    boost::asio::占位符::错误,
    boost::asio::占位符::字节(已传输);
    }
    模板
    大小\u t MessageReader::bytesToRead(常量错误\u代码和错误,
    大小\u t字节\u读取)
    {
    结果的大小;
    如果(错误)
    结果=0;//错误-停止读取
    else if(字节读取header.byteCount>sizeof(*readBuffer))
    结果=0;//字节计数错误
    其他的
    result=readBuffer->header.byteCount-bytes\u read;//读取消息正文
    返回结果;
    }
    模板
    void MessageReader::readDone(常量错误\u代码和错误,
    大小\u t字节\u读取)
    {
    如果(错误)
    {
    if(error.value()==boost::system::errc::no_这样的文件或目录)
    {
    notifyStop();
    }
    else if(error.value()!=boost::system::errc::操作\u已取消)
    {
    notifyStop();
    }
    //否则操作被取消,因此不需要停止通知,并且
    //我们只能回去
    }
    else if(bytes\u read!=readBuffer->header.byteCount)
    {
    LOG4CXX_错误(记录器,“消息字节计数不匹配”);
    notifyStop();
    }
    其他的
    {
    handleMsg(readBuffer);
    星纹();
    }
    }
    

    编辑:为错误代码添加了typedef。

    我昨天这样做了。所以我想我会提供我的解决方案

    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    
    #include <boost/asio.hpp>
    #include <boost/asio/streambuf.hpp>
    
    void ReadFromStreambuf()
    {
        boost::asio::streambuf mybuffer;
    
        // write some data to the buffer
        std::ostream o2buffer (&mybuffer);
        o2buffer << "hello stackoverflow";
    
        // get buffer size
        size_t nBufferSize = boost::asio::buffer_size(mybuffer.data());
    
        // get const buffer
        std::stringstream ssOut;
        boost::asio::streambuf::const_buffers_type constBuffer = mybuffer.data();
    
        // copy const buffer to stringstream, then output
        std::copy(
            boost::asio::buffers_begin(constBuffer),
            boost::asio::buffers_begin(constBuffer) + nBufferSize,
            std::ostream_iterator<char>(ssOut)
        );
    
        std::cout << ssOut.str() << "\n";
    }
    
    
    int main(int argc, char const *argv[])
    {
        ReadFromStreambuf();
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    void ReadFromStreambuf()
    {
    boost::asio::streambuf mybuffer;
    //将一些数据写入缓冲区
    std::ostream o2buffer(&mybuffer);
    
    谢谢,我接受了你的建议。
    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    
    #include <boost/asio.hpp>
    #include <boost/asio/streambuf.hpp>
    
    void ReadFromStreambuf()
    {
        boost::asio::streambuf mybuffer;
    
        // write some data to the buffer
        std::ostream o2buffer (&mybuffer);
        o2buffer << "hello stackoverflow";
    
        // get buffer size
        size_t nBufferSize = boost::asio::buffer_size(mybuffer.data());
    
        // get const buffer
        std::stringstream ssOut;
        boost::asio::streambuf::const_buffers_type constBuffer = mybuffer.data();
    
        // copy const buffer to stringstream, then output
        std::copy(
            boost::asio::buffers_begin(constBuffer),
            boost::asio::buffers_begin(constBuffer) + nBufferSize,
            std::ostream_iterator<char>(ssOut)
        );
    
        std::cout << ssOut.str() << "\n";
    }
    
    
    int main(int argc, char const *argv[])
    {
        ReadFromStreambuf();
        return 0;
    }