加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

boost::asio 中async_read与async_receive,async_read_some的区别

(2012-07-31 15:09:47)
标签:

杂谈

分类: boost
boost::asio 中async_read与async_receive的区别

现象:在调用async_read后,即使收到数据包,也没有调用相应的ReadHandler 回调函数


void handle_connect(const boost::system::error_code & error,
       tcp::resolver::iterator endpoint_iterator)
   {
       if(!error)
       {
           socket_.async_receive(boost::asio::buffer(buf_),            
               boost::bind(&tcp_client::handler_read_response,this,
               boost::asio::placeholders::error,
               boost::asio::placeholders::bytes_transferred));
                       //直到收到的字节数能够填满buf_(即256个字节)或出错,才调用handler_read_responsehandler_read_response;否则即使收到包也不进行处理。

           boost::asio::async_read(socket_,boost::asio::buffer(buf_),
               boost::bind(&tcp_client::handler_read_response,this,
               boost::asio::placeholders::error,
               boost::asio::placeholders::bytes_transferred));
                     //一旦收到数据或出错,就调用handler_read_response
       }
}
tcp::socket socket_;
boost::array buf_;
void handler_read_response(const boost::system::error_code & error, size_t ) //注意类型,error有引用,而bytes_transferred没有引用


//声明:boost/asio/read.hpp
template     
void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
    ReadHandler handler);

//定义: boost/asio/impl/read.hpp
* @code void handler(
*   const boost::system::error_code& error, // Result of operation.
*
*   std::size_t bytes_transferred           // Number of bytes copied into the
*                                           // buffers. If an error occurred,
*                                           // this will be the  number of
*                                           // bytes successfully transferred
*                                           // prior to the error.
* );
template 
    typename ReadHandler>
inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
    ReadHandler handler)
{
 async_read(s, buffers, transfer_all(), handler);
}
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
* @code boost::asio::async_read(s,
*     boost::asio::buffer(data, size),
*     boost::asio::transfer_at_least(32),
*     handler); @endcode
* See the @ref buffer documentation for information on reading into multiple
* buffers in one go, and how to use it with arrays, boost::array or
* std::vector.
*/
template 
    typename CompletionCondition, typename ReadHandler>
void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
    CompletionCondition completion_condition, ReadHandler handler);

 template 
 void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
 {
    this->service.async_receive(this->implementation, buffers, 0, handler);
 }

结论:

async_receive包含有CompletionCondition, 在调用
void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,ReadHandler handler)时,必须等到填满Buffer,否则即使收到数据包,也不会没有调用ReadHandler句柄;
async_read只要收到数据,就会被调用


Async_read_some async_receive 对比

已有 973 次阅读2010-10-18 16:40 |个人分类:boost|

 asio::async_read通常用户读取指定长度的数据,读完或出错才返回。
 而socket的async_read_some读取到数据或出错就返回,不一定读完了整个包。  
 

Tcp::socket::Async_read_some,tcp::socket:: async_receive 和asio::async_read

Socket::async_read_some和socket::async_receive是一样的,唯一的细小区别是,socket::async_receive提供两种接口,其中一种增加了flags参数。因为绝大多数flags=0,所以这两个函数可以看成没区别。

Socket::async_write_some和socket::async_send也是一样的,唯一的细小区别依然是socket::async_send提供良种接口,其中一种增加了flags参数。

Asio::async_read有多种接口形式,最基本的一种是

template<
typename AsyncReadStream,
typename MutableBufferSequence,
typename ReadHandler>
void async_read(
AsyncReadStream & s,
const MutableBufferSequence & buffers,
ReadHandler handler);

这种模式下,必须等到buffers全都被填满了,或者错误发生,才会进入完成函数。

如果希望收到特定数量的字节以上即进入完成函数,则应该调用

template<
typename AsyncReadStream,
typename MutableBufferSequence,
typename CompletionCondition,
typename ReadHandler>
void async_read(
AsyncReadStream & s,
const MutableBufferSequence & buffers,
CompletionCondition completion_condition,
ReadHandler handler);

这个CompletionCondition的实现方法可以参考completion_condition.hpp中的transfer_at_least,当然也可以实现其他更复杂的condition class。这个CompletionCondition class非常简单,只需要实现operator(error,bytestransfer)即可。

猜想如果transfer_at_least(1),则类似于socket::async_read_some

另外两个接口形式为:

template<
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
void async_read(
AsyncReadStream & s,
basic_streambuf< Allocator > & b,
ReadHandler handler);
template<
typename AsyncReadStream,
typename Allocator,
typename CompletionCondition,
typename ReadHandler>
void async_read(
AsyncReadStream & s,
basic_streambuf< Allocator > & b,
CompletionCondition completion_condition,
ReadHandler handler);

这两个函数和上面2个函数的区别应该是basic_streambuf<Allocator>的区别,可能可以自定义分配方式。

 

write系列函数类此。

一般来说,接收和发送时均应该使用asio::async_read/write,如果接收时协议无清晰格式,例如没有一个固定长度的header_len,则使用socket::async_read_some

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有