c++ boost::asio::async_read與Socket的async_read_some的區別

 boost::asio::async_read(socket(), boost::asio::buffer(request_->buffer(), read_len),
          boost::bind(&tcp_connection::HandleReadCardKey, shared_from_this(),
           asio::placeholders::error));

但HandleReadCardKey始終沒有被回調,除非remote point斷開連接

最後用下面的代碼搞定:

socket.async_read_some(boost::asio::buffer(request_->buffer() read_len),
         boost::bind(&tcp_connection::HandleReadCardKey, shared_from_this(),
        asio::placeholders::error));

記下,免得以後忘記了

總結一下:
    1:  asio::async_read通常用戶讀取指定長度的數據,讀完或出錯才返回(會超指定buffer的長度,

不信,你可有用ssl的方式寫一個https的通信,用from-urlencoded方式傳遞下試試)
      而socket的async_read_some讀取到數據或出錯就返回,不一定讀完了整個(不會超指定buffer的長度),如果再次讀取,這函數被阻塞,直到有數據才通知回調(邊緣觸發模式)

    2:以上兩種方式方式,讀完數據之後,內核中buffer的data會被拷貝走

    3:建議使用async_read_some函數,一定不會出錯,出錯說明代碼問題

解決思路:

接上上面的問題,可以把    boost::asio::async_read(*socket_, boost::asio::buffer(buffer_,buffer_.size()),boost::asio::transfer_exactly(buffer_.size())(這樣操作比較保險,但又會引發第二問題:若內核的緩衝區的數據長度大於指定的長度,會引發當前數據阻塞,因此此方法不叫保險,不會發生數據越界問題)

再細說一句:

boost::asio::buffer裏面的參數填string對象和vector<char>對象,有可能發生內存越界(使用async_read方法)

再囉嗦幾句:

transfer_exactly 函數是讀指定字節

transfer_all  讀所有

transfer_at_least 至少讀指定字節

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章