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

为了实现一个收到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的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值