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

Boost.Asio-其他特性
这章我们讲了解一些Boost.Asio不那么为人所知的特性。标准的stream和streambuf对象有时候会更难用一些,但正如你所见,它们也有它们的益处。最后,你会看到姗姗来迟的Boost.Asio协程的入口,它可以让你的异步代码变的非常易读。这是非常惊人的一个特性。

标准stream和标准I/O buffer
读这一章节之前你需要对STL stream和STL streambuf对象有所了解。
Boost.Asio在处理I/O操作时支持两种类型的buffer:
  • boost::asio::buffer():这种buffer关联着一个Boost.Asio的操作(我们使用的buffer被传递给一个Boost.Asio的操作)
  • boost::asio::streambuf:这个buffer继承自std::streambuf,在网络编程中可以喝STL stream一起使用
纵观全书,之前的例子中最常见的例子如下:
  1. size_t read_complete(boost::system::error_code, size_t bytes){ ... }
       char buff[1024];
       read(sock, buffer(buff), read_complete);
       write(sock, buffer("echo\n"));
    
通常来说使用这个就能满足你的需要,如果你想要更复杂,你可以使用streambuf来实现。
这个就是你可以用streambuf对象做的最简单也是最坏的事情:

streambuf buf;

   read(sock, buf);
这个会一直读到streambuf对象满了,然后因为streambuf对象可以通过自己重新开辟空间从而获取更多的空间,它基本会读到连接被关闭。
你可以使用read_until一直读到一个特定的字符串:

streambuf buf;

read_until(sock, buf, "\n");

这个例子会一直读到一个“\n”为止,把它添加到buffer的末尾,然后退出read方法。
向一个streambuf对象写一些东西,你需要做一些类似下面的事情:

streambuf buf;
   std::ostream out(&buf);
   out << "echo" << std::endl;
   write(sock, buf);
这是非常直观的;你在构造函数中传递你的streambuf对象来构建一个STL stream,将其写入到你想要发送的消息中,然后使用write来发送buffer的内容。

Boost.Asio和STL stream
Boost.Asio在集成STL stream和网络方面做了很棒的工作。也就是说,如果你已经在使用STL扩展,你肯定就已经拥有了大量重载了操作符<<和>>的类。从socket读或者写入它们就好像在公园漫步一样简单。
假设你有下面的代码片段:
struct person {
       std::string first_name, last_name;
       int age;
   };
   std::ostream& operator<<(std::ostream & out, const person & p) {
       return out << p.first_name << " " << p.last_name << " " << p.age;
   }
std::istream& operator>>(std::istream & in, person & p) {
    return in >> p.first_name >> p.last_name >> p.age;

通过网络发送这个person就像下面的代码片段这么简单:
streambuf buf;
   std::ostream out(&buf);
   person p;
   // … 初始化p
   out << p << std::endl;
   write(sock, buf);
另外一个部分也可以非常简单的读取:
read_until(sock, buf, "\n");
   std::istream in(&buf);
   person p;
   in >> p;
使用streambuf对象,当然,也包括它用来写入的std::ostream和用来读取的std::istream时最棒的部分就是你最终的编码会很自然:
  • 当通过网络写入一些要发送的东西时,很有可能你会有多个片段的数据。所以,你需要把数据添加到一个buffer里面。如果那个数据不是一个字符串,你需要先把它转换成一个字符串。当使用<<操作符时这些操作默认都已经做了
  • 同样,在另外一个部分,当读取一个消息时,你需要解析它,也就是说,读取到一个片段的数据时,如果这个数据不是字符串,你需要将它转换为字符串。当你使用>>操作符读取一些东西时这些也是默认就做了的
最后要给出的是一个非常著名,非常酷的诀窍,使用下面的代码片段把streambuf的内容输出到console中
  1. streambuf buf;
       ...
       std::cout << &buf << std::endl; // 把所有内容输出到console中
    
同样的,使用下面的代码片段来把它的内容转换为一个string:
  1. std::string to_string(streambuf &buf) {
           std::ostringstream out;
           out << &buf;
           return out.str();
    


你可能感兴趣的:(C++,异步,网络编程,asio,boost)