Boost.Asio c++ 网络编程翻译(9)

时间:2022-09-08 23:52:15

PS:昨天加班到凌晨,今天睡得天昏地暗…


缓冲区函数包装

纵观所有代码你会发现:无论什么时候,当我们需要对一个buffer进行读写操作时,代码会把实际的缓冲区对象包装在一个buffer()方法中,然后在把它传递给方法调用:
char buff[512];
   sock.async_receive(buffer(buff), on_read);
基本来说我们把任何缓冲区包含在一个类中以便Boost.Asio的方法能遍历这个缓冲区,比方说,你使用下面的代码: 
 
    
sock.async_receive(some_buffer, on_read);
实例some_buffer会遇到一些需求,叫做ConstBufferSequence或者MutableBufferSequence(你可以在Boost.Asio的文档中查看它们)。创建你自己的类去处理这些需求的细节是非常复杂的,但是Boost.Asio已经提供了一些类用来处理这些需求。所以你不用直接访问这些缓冲区,而使用buffer()方法。
自信地讲,你可以把下面列出来的类型都包装到一个buffer()方法中:
一个char[] const 数组
一个字节大小的void *指针
一个std::string类型的字符串
一个POD const数组(POD代表纯数据,不做任何操作的构造器和释放器)
一个pod数据的std::vector
一个包含pod数据的boost::array
一个包含pod数据的std::array
下面的代码都是有效的:
 
       
  1. struct pod_sample { int i; long l; char c; };
       ...
       char b1[512];
       void * b2 = new char[512];
    
       std::string b3; b3.resize(128);
       pod_sample b4[16];
       std::vector<pod_sample> b5; b5.resize(16);
       boost::array<pod_sample,16> b6;
       std::array<pod_sample,16> b7;
       sock.async_send(buffer(b1), on_read);
       sock.async_send(buffer(b2,512), on_read);
       sock.async_send(buffer(b3), on_read);
       sock.async_send(buffer(b4), on_read);
       sock.async_send(buffer(b5), on_read);
       sock.async_send(buffer(b6), on_read);
       sock.async_send(buffer(b7), on_read);
    
总的来说就是:与其创建你自己的类来处理ConstBufferSequence或者MutableBufferSequence的需求,不如创建一个能在你需要的的时候保留缓冲区,然后返回一个mutable_buffers_1实例的类,而我们早在shared_buffer类中就这样做了。 read/write/connect*函数
Boost.Asio提供了*函数来让你处理I/O,我们分四组来分析它们。
connect方法
这些方法把套接字连接到一个端点。
connect(socket, begin [, end] [, condition]):这个方法通过尝试队列中从start到end的端点来同步连接。begin迭代器是socket_type::resolver::query调用的返回结果(你可能需要回顾一下端点这个章节)。特别提示end迭代器是可选的;你可以忽略它。你可以提供一个condition的方法供每次连接尝试之后调用。用法是Iterator connect_condition(const boost::system::error_code & err,Iterator next);。你可以选择返回一个不是next的迭代器,这样就你可以跳过一些端点。 async_connect(socket, begin [, end] [, condition], handler):这个方法异步地调用连接方法,在结束时,它会调用完成处理方法。用法是void handler(constboost::system::error_code & err, Iterator iterator);。传递给处理方法的第二个参数是连接成功的端点的迭代器。(或者end迭代器)。
它的例子如下:
using namespace boost::asio::ip;
tcp::resolver resolver(service);
tcp::resolver::iterator iter = resolver.resolve( tcp::resolver::query("www.yahoo.com","80"));
tcp::socket sock(service);
connect(sock, iter);
一个主机名可以被解析成多个地址,而connect和async_connect能让你很好的从尝试每个地址然后找到一个可用地址的繁重工作中解放出来,因为它们已经帮你做了这些。