gpt4 book ai didi

c++ - 当 streambuf 被之前的 async_read 填充时,boost::asio::async_read 进入 boost::asio::streambuf block

转载 作者:搜寻专家 更新时间:2023-10-31 01:56:54 25 4
gpt4 key购买 nike

我搜索了其他帖子,但没有找到任何相关内容。现在,我有一个由 header 和正文组成的协议(protocol)。协议(protocol)是这样的:Z24,91009802,123456789ABCDEF其中 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;
}
}

现在,标题被读取了。但是阅读页脚 block 。显然,整个消息都在 header 调用中读取。当我使用 boost::asio::transfer_at_least(nBytes) 执行第二个 async_read() 时,nBytes 已经在 inputStreamBuffer_ 中,但我认为调用不会检查这个?

这是输出的转储:

request_=#Z24,#n字节=24尺寸=24

问题是什么,或者我该如何解决。我是一个 boost 新手,所以所有的帮助表示赞赏。谢谢。

编辑:我试图检查缓冲区的完整性,如果它恰好已被先前的调用读取,则不要对主体进行 async_read() 调用。它有点管用,但它是正确的解决方案吗?

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;
}
}

最佳答案

The Boost ASIO documentation表示 async_read_until 调用可能会将超出定界符的数据读入缓冲区(请参阅备注部分)。话虽如此,根据您的输入,您检查缓冲区是否有更多数据的解决方案是一个很好的解决方案。

正如我在上面的评论中提到的,如果您的要求允许您这样做,则对剩余字节使用整数值而不是字符串可能会让您的生活更轻松,并且代码更清晰,错误更少俯卧。

关于c++ - 当 streambuf 被之前的 async_read 填充时,boost::asio::async_read 进入 boost::asio::streambuf block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6370834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com