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

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