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);

另外一个部分也能够很easy的读取:

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();
    

}

时间: 2024-12-26 08:30:51

Boost.Asio c++ 网络编程翻译(26)的相关文章

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

第一次翻译,希望大家多多指正 实战出精华 Boost.Asio C++ 网络编程 用具体的C++网络编程例子来提升你的技能 John Torjan 用具体的C++网络编程例子来提升你的技能 Copyright ? 2013 Packt Publishing 版权所有,除了在鉴定文章或者评论中进行简单引用,如果没有经过出版者事先的书面授权,该书的任何部分都不能被转载.存储在检索系统中.或者以任何形式和方式传阅. 在这本书准备发行之前,我们已经尽我们最大的努力去保证书中信息的准确性.但是,这本书中包

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

异步服务端 这个图表是相当复杂的:从Boost.Asio出来你可以看到4个箭头指向on_accept,on_read,on_write和on_check_ping.着也就意味着你永远不知道哪个异步调用是下一个完成的调用,但是你可以确定的是它是这4个操作中的一个. 现在,我们是异步的了:我们可以继续保持单线程.接受客户端连接是最简单的部分,如下所示: ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001)

Boost.Asio c++ 网络编程翻译(30)[完结]

PS:至此终于完成了Boost.Asio C++ network programming一书的翻译,这是我人生第一本完整翻译的书,从开始的磕磕绊绊,到最后小有心得,我收获很多.我将把这个系列的博客进行整理和校对,希望有兴趣的人可以帮我一起,来给大家提供更好更专业的阅读体验. 句柄追踪信息到文件 默认情况下,句柄的追踪信息被输出到标准错误流(相当于std::cerr).你想把输出重定向到其他地方的可能性是非常高的.对于控制台应用,输出和错误输出都被默认输出到相同的地方,也就是控制台.但是对于一个w

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

保持活动 假如,你需要做下面的操作: io_service service; ip::tcp::socket sock(service); char buff[512]; ... read(sock, buffer(buff)); 在这个例子中,sock和buff的存在时间都必须比read()调用的时间要长.也就是说,在调用read()返回之前,它们都必须有效.这就是你期望的:你传给一个方法的所有参数在参数内部都必须有效.当我们采用异步方式时,事情会变得越复杂. io_service servi

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

Boost.Asio入门 什么是Boost.Asio 简单来说,Boost.Asio是一个跨平台的.主要用于网络和其他一些底层输入/输出编程的C++库. 计算机网络的设计方式有很多种,但是Boost.Asio的的方式远远优于它们.它在2005年就被包含进Boost,然后被广大Bosot的用户测试并在很多项目中使用,比如Remobo(http://www.remobo.com),可以让你创建你自己的即时私有网络(IPN),libtorrent(http://www.rasterbar.com/pr

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

*_at方法 这些方法在一个流上面做随机存取操作.你来指定read和write操作从什么地方開始(offset): async_read_at(stream, offset, buffer [, completion], handler):这种方法在一个指定的流上从offset处開始运行一个异步的read操作,当操作结束时,他会调用handler. handler的格式为:void handler(const boost::system::error_code&  err, size_t byt

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

io_service类 你应该已经发现大部分使用Boost.Asio编写的代码都会使用几个ios_service的实例.ios_service是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用完成处理程序. 如果你选择用同步的方式来创建你的应用,你不需要考虑我将在这一节向你展示的东西. 你可以用几种不同的方式来使用io_service.在下面的例子中,我们有3个异步操作,2个socket连接和一个计时器等待: 有一个io_service和一个处理线程

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

Boost.Asio基本原理 这一章涵盖了你使用Boost.Asio时必须知道的一些事情.我们也将深入研究比同步编程更机警.更有乐趣的异步编程. 网络API 这一部分包含了当使用Boost.Asio编写网络应用程序时你必须知道的事情. Boost.Asio命名空间 Boost.Asio的一切都需要包含在boost::asio的命名空间或者其子命名空间内. boost::asio:这是核心类和函数所在的地方.重要的类有io_service和streambuf.类似read, read_at, re

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

同步VS异步 首先,异步编程和同步编程是有极大的不同的.在同步编程中,你所有的操作都是顺序执行的,比如从一个socket中读取(请求),然后写入(回应)到socket中.每一个操作操作都是阻塞的.因为操作是阻塞的,所以为了不影响主程序,当读写一个socket时,通常创建一个或多个线程来处理socket的输入/输出.因此,同步的服务端/客户端通常是多线程的. 相反的,异步编程是事件驱动的.你启动了一个操作,但是你不知道它何时会结束:你只是提供一个回调,当操作结束时,它会调用这个API,并返回操作结