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 至少讀指定字節