博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

boost asio api

Posted on 2015-07-03 15:22  bw_0927  阅读(445)  评论(0)    收藏  举报

http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/reference.html

http://www.cnblogs.com/my_life/articles/4911769.html

 

async_write

This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:

  • All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
  • An error occurred.

 

https://www.avboost.com/t/asio/245

另外:常常在网上有人说到,关于同时多次调用async_send的之类的问题(类似的有同时WSASend多次),首先说下,不要在项目中使用这种傻逼的方式编程,因为多次async_send之类的操作行为是不能确定的,你不停的调用async_send,而不等待上一次async_send调用的完成,这样做,结果可能是某次发送是不完整的,不要试图做这种傻事,也不要研究如何通过多次async_send来提高发送效率,因为一开始就犯了方向性错误!

 

buffers

asio::buffer 是一个用作缓冲的warpper,它本身不管理内存,这一点要牢记

 

{
  std::string str = "hello";
  async_write(asio::buffer(str), handler);
}

这样的代码是可能会挂掉的,没挂掉是运气,也就是:

传进异步方法的东西都要明确的保证能活到他被用到的时候 这个很关键!

asio的各种异步/同步函数的buffer参数,可以支持多段不同的缓冲区:

 

std::vector<const_buffer> bufs2;
bufs2.push_back(boost::asio::buffer(d1));
bufs2.push_back(boost::asio::buffer(d2));
bufs2.push_back(boost::asio::buffer(d3));
bytes_transferred = sock.send(bufs2);

比如像上面 已经是个vector容器了

发送时,一段一段的连着,接收也是一段一段的连着,利用多段 buffer 可以很优雅的实现数据处理而无需手写 struct。

 

strand
--

strand 用于保证回调有顺。

strand内部是个队列,在队列中如果还有未执行的handler,新的投递,将会加入队列,如果队列为空,则将直接投递到系统

 

streambuf
--

streambuf,是个非常好的变长buffer。
streambuf可以结合std::iostream 处理。
streambuf也可以把数据取出来,当作buffer处理,sgetn之类的函数,可以让你做到。
特别适合用来配合 read_until这类条件读取。

条件传输
--

asio 的 io 还提供了以条件作为操作终止条件的,并内置了:

  • transfer_all
  • transfer_at_least
  • transfer_exactly

三个条件,你也可以自己定制自己的条件对象来处理自己需要的方式,比如avhttp中的async_read_body.hpp就是一个很好的范例。

read_until
--

在这个实现中,实际上,每次是读取一块固定大小的长度,比如可能是512byte,然后在streambuf中match你的完成条件.一旦match到,将返回完成这次操作。

并返回match到的字节数,而不是读取到的

多读取到的部分,用于下次 read_until,因此下次 read_until 可能并不需要进入系统读取数据,也能返回数据哦~

比如对方发送的数据是 "123456789"

你使用 read_until(streambuf, "4", handler);

其实第一次读取,已经将 "123456789" 存入 streambuf,但是 readuntil返回长度是4。

这时,你如果只从streambuf中,取出了前4个字符,再继续使用 read_until(streambuf, "9", handler); 读取时,asio会直接将上一次读取的东西返回并返回读取的字节数为 5,而不是发起新的读取操作。