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

异步run(), run_one(), poll(), poll_ one()

为了实现监听循环,io_service类提供了4个方法,比如:run(), run_one(), poll()和poll_one()。当大部分时间你使用service.run()就可以。你会在这里学习到其他方法完成了什么。

持续运行

再一次说明,如果有等待执行的操作,run()会一直执行,直到你手动调用io_service::stop()。为了保证io_service一直执行,通常你添加一个或者多个异步操作,然后当它们被执行时,你继续一直不停地添加异步操作,比如下面代码:

using namespace boost::asio;

io_service service;

ip::tcp::socket sock(service);

char buff_read[1024], buff_write[1024] = "ok";

void on_read(const boost::system::error_code &err, std::size_t bytes)

;

void on_write(const boost::system::error_code &err, std::size_t bytes)

{

sock.async_read_some(buffer(buff_read), on_read);

}

void on_read(const boost::system::error_code &err, std::size_t bytes)

{

// ... process the read ...

Chapter 2

[ 45 ]

sock.async_write_some(buffer(buff_write,3), on_write);

}

void on_connect(const boost::system::error_code &err) {

sock.async_read_some(buffer(buff_read), on_read);

}

int main(int argc, char* argv[]) {

ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"),

2001);

sock.async_connect(ep, on_connect);

service.run();

}

当service.run()被调用时,有一个异步操作在等待。当套接字连接到服务端时,on_connect被调用了,它会添加一个异步操作。当on_connect结束时,我们会留下一个等待的操作(read)。当on_read被调用时,我们写入一个回应,这又添加了另外一个等待的操作。当on_read结束时,我们会留下一个等待的操作(write)。当on_write操作被调用时,我们从服务端读取另外一个消息,这也添加了另外一个等待的操作。当on_write结束时,我们有一个等待的操作(read)。然后循环一直继续下去,直到我们关闭这个应用

run_one(), poll(), poll_one() 方法

我在之前说过异步方法handler是在之前调用了io_service::run的线程里被调用的。因为至少在90%到95%的时候,这是你唯一要用到的方法,所以我就把它说的简单了。对于调用了run_one(), poll(), or poll_one()的线程这一点也是适用的。

run_one()方法最多执行和分发一个异步操作:

如果没有等待的操作,方法立即返回0

如果由等待操作,方法在第一个操作执行之前处于阻塞状态,然后返回1

你可以认为下面两段代码是等效的:

io_service service;

service.run(); // 或者

while ( !service.stopped()) service.run_once();

你可以使用run_once()启动一个异步操作,然后等待它执行完成。

io_service service;

bool write_complete = false;

void on_write(const boost::system::error_code & err, size_t bytes)

{ write_complete = true; }

std::string data = "login ok”;

write_complete = false;

async_write(sock, buffer(data), on_write);

do service.run_once() while (!write_complete);

还有一些使用run_one()方法的例子,包含在Boost.Asio中比如blocking_tcp_client.cpp和blocking_udp_client.cpp中。

poll_one方法使用非阻塞的方式最多运行一个准备好运行的等待操作:

如果至少有一个等待的操作,而且准备好以非阻塞的方式运行,poll_one方法会运行它并且返回1

否则,方法立即返回0

操作等待,准备以非阻塞方式运行,通常意味着如下的情况:

一个计时器过期了,然后它的async_wait处理方法需要被调用

一个I/O操作完成了(比如async_read),然后它的hanlder需要被调用

之前被加入io_services实例队列中的自定义handler(这会在之后的章节中详解)

你可以使用poll_one去保证所有I/O操作的handler完成运行,同时做一些其他的工作

io_service service;

while ( true) {

// 运行所有完成了IO操作的handler

while ( service.poll_one()) ;

// ... 在这里做其他的事情 …

}

poll()方法会以非阻塞的方式运行所有等待的操作。下面两段代码是等效的:

io_service service;

service.poll(); // 或者

while ( service.poll_one()) ;

所有之前的方法都会在失败的时候抛出boost::system::system_error异常。而这是永远不应该发生的事情;这里抛出的异常通常都是致命的,也许是资源耗尽,或者是你其中一个handler抛出了异常。另外,每个方法都由一个不抛出异常,而是返回一个boost::system::error_code的重载:

io_service service;

boost::system::error_code err = 0;

service.run(err);

if ( err) std::cout << "Error " << err << std::endl;

时间: 2024-10-18 08:21:26

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

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++ 网络编程翻译(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++ 网络编程翻译(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++ 网络编程翻译(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++ 网络编程翻译(26)

Boost.Asio-其他特性 这章我们讲了解一些Boost.Asio不那么为人所知的特性.标准的stream和streambuf对象有时候会更难用一些,但正如你所见.它们也有它们的益处.最后,你会看到姗姗来迟的Boost.Asio协程的入口,它能够让你的异步代码变的很易读.这是很惊人的一个特性. 标准stream和标准I/O buffer 读这一章节之前你须要对STL stream和STL streambuf对象有所了解. Boost.Asio在处理I/O操作时支持两种类型的buffer: b

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