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