• boost::async_read_some连续接收数据


    我在最近工作的时候用到了boost的http_server程序,这个http_server是一个框架用于接收并解析http协议。这个框架在接收get请求时没有任何问题,当接收post数据时,当数据大于>2k时,无法正确接收,后来发现sync_read_some函数一次只能接收大约1k数据,如果要接收大数据,需要反复接收,自己修改了几天,将经验分享一下。
    //接收数据的buffer
    boost::array<char, 8192> buffer_;
    //数据需要多次接收,将多次接收的数据都放入data中
    std::string data;
    void connection::start()
    {
    //超时限制
      timer.expires_from_now(boost::posix_time::microseconds(1000000));
      timer.async_wait(boost::bind(&connection::close_connect1,this)); 
    
      buffer_.data()[0] = '';
      //开始接收数据
      socket_.async_read_some(boost::asio::buffer(buffer_),
      boost::bind(&connection::handle_read1, shared_from_this(),
      boost::asio::placeholders::error,       
      boost::asio::placeholders::bytes_transferred,data));
      return;
    }void connection::handle_read1(const boost::system::error_code& e,std::size_t bytes_transferred,string& data)
    {
    //如果超时,返回空
    if(!m_flag)
    {
    m_flag = true;
        request_handler_.handle_request1(request_, reply_);
       boost::asio::async_write(socket_, reply_.to_buffers(),
       boost::bind(&connection::handle_write, shared_from_this(),
       boost::asio::placeholders::error));
       
       boost::system::error_code ignored_ec;
        socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
       return;
    }
    //如果接收有错误或者接收的数据长度=0,和超时处理一致
    if(e || bytes_transferred==0)
    {
    request_handler_.handle_request1(request_, reply_);
          boost::asio::async_write(socket_, reply_.to_buffers(),
              boost::bind(&connection::handle_write, shared_from_this(),
                boost::asio::placeholders::error));
        boost::system::error_code ignored_ec;
        socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
        return;
    }else
    {
    buffer_.data()[bytes_transferred] = '';
    data = data + buffer_.data();
    //表示接收到了结束标志
    if (data.find("|*|*|") != string::npos)
    {
    int pos = data.find("|*|*|");
    printf("pos=%d
    ",pos);
        data = data.substr(0,pos);
        
            if(data.length()>0)
            {
    //时钟取消
            timer.cancel();
            //用于处理接收的数据并将处理完的数据返回去,处理完的数据存储在reply中
             request_handler_.handle_request_pos(request_, reply_,data);
             boost::asio::async_write(socket_, reply_.to_buffers(),
                  boost::bind(&connection::handle_write, shared_from_this(),
                    boost::asio::placeholders::error));
            }
            else{
            request_handler_.handle_request1(request_, reply_);
              boost::asio::async_write(socket_, reply_.to_buffers(),
                  boost::bind(&connection::handle_write, shared_from_this(),
                    boost::asio::placeholders::error));
            }
            boost::system::error_code ignored_ec;
            socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
            return;
        
      }


  • 相关阅读:
    C#窗体操作的小技巧
    C#操作Xml
    Path类对路径字符串的操作
    Google Maps 基础
    C#时间操作总结
    根据地理坐标计算瓦片行列号
    使用VBA宏批量修改表格
    检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法
    Asp.net实现URL重写
    VS2013利用ajax访问不了json文件——VS2013配置webconfig识别json文件
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318604.html
Copyright © 2020-2023  润新知