【发布时间】:2011-06-16 11:10:43
【问题描述】:
我搜索了其他帖子,但没有找到任何相关内容。 现在,我有一个由标头和正文组成的协议。 协议如下: 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;
}
}
现在,标题已被读取。但是阅读页脚块。显然,整个消息是在标头调用中读取的。当我使用 boost::asio::transfer_at_least(nBytes) 执行第二个 async_read() 时,nBytes 已经在 inputStreamBuffer_ 中,但我认为调用没有检查这个?
这是输出中的转储:
请求_=#Z24,# nBytes=24 大小=24
是什么问题,或者我该如何解决它。我是一个提升新手,所以所有的帮助表示赞赏。谢谢。
编辑: 我试图检查缓冲区的完整性,如果它恰好已被先前的调用读取,则不要对主体进行 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;
}
}
【问题讨论】:
-
在对主体执行 async_read() 之前,我尝试检查缓冲区填充度。我有点工作。这是正确的解决方案吗?
-
我不确定您的要求是否允许您这样做,但通常更容易使用已定义字节大小的整数值来表示要读取的剩余字节,而不是可变长度的字符串。
标签: c++ boost boost-asio