您的位置:首页 > 理论基础 > 计算机网络

boost 库asio网络接口收取数据缺失的分析

2017-11-04 12:16 781 查看
为了实现一个收到HTTPS响应的接口,我的实现思路是这样的:
分三步对响应进行接收,第一步先接收response_line, 第二步接收response_header , 最后一步对reponse_body进行接收。
在代码上,因为前两步都有明显的结束标识符,response line使用"\r\n"作为结束标识库,response header使用"\r\n\r\n"作为结束标识库,这些都是HTTP标准规定的,所以不会有问题,而response body使用一个计时器,当接收超时100ms后,表示当前body已经接收完成。
代码逻辑如下:
读取response line:
asio::async_read_until(socket_,
response_,
MatchResponseLine,
bind(&HttpsWebClient::OnReadResponseLineHandler,

this,
web_response,
response_handler,
asio::placeholders::error,
asio::placeholders::bytes_transferred)
);

MatchResponseLine中对"\r\n"进行遍历,找到就返回相应的response_迭代器位置,然后读取完成后调用回调函数OnReadResopnseLineHandler

读取reponse header:
asio::async_read_until(socket_,
response_,
MatchResponseHeader,
bind(&HttpsWebClient::OnReadResponseHeaderHandler,

this,
web_response,
response_handler,
asio::placeholders::error,
asio::placeholders::bytes_transferred)
);

解析如上。

读取response body:
socket_.async_read_some(
asio::buffer(read_data_buffer_, READ_DATA_BUFFER_SIZE),
bind(&HttpsWebClient::OnReadResponseBodyHandler, this,
web_response,
response_handler,
asio::placeholders::error,
asio::placeholders::bytes_transferred)

这三次调用是顺序调用的,也就是在OnReadResponseLineHandler中调用了read response header, 然后在OnReadResonseHeaderHandler中调用了read reponse body.

然后就出现了问题,当读取reponse line和reponse body时就能够正常的拿到所有数据。但最后一步读取reponse body的时候就发现body的前120个字节不见了。
一开始以为是boost 的 asyn_read_some接口出问题了,上google查了下发现没有人有遇到类似的问题,但还是换了下接口,换成asyn_read,改了下相关的逻辑,发现没有办法解决问题。于是就开始怀疑是缓冲区的处理的问题,
使用单步调试进入MatchResponseHeader中,发现在read response header的时候就已经把body的一部分数据读到了response_缓冲区中了,而当我们去读body的时候,使用了另外一个缓冲区read_data_buffer_缓冲区,导致了body开头的数据丢失。
所以发现问题后,解决方法就是在read response body中也使用相同的response_缓冲区。
修改后的代码如下:
asio::async_read(socket_,
response_,
//asio::buffer(read_data_buffer_,
READ_DATA_BUFFER_SIZE),
boost::asio::transfer_at_least(1),
bind(&HttpsWebClient::OnReadResponseBodyHandler,

this,
web_response,
response_handler,
asio::placeholders::error,
asio::placeholders::bytes_transferred)
);
验证后证明是OK的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ boost asio http