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 至少读指定字节