boost::asio基本使用
一、Asio网络库
截止到C++17,C++标准库都没有加入网络通信库。实际项目网络编程是非常常见的功能,直接使用操作系统API是低效率且不稳定的,比较好的方法是借助第三方成熟可靠的网络库。据我所知C++中目前比较有名的网络库有ACE、libevent和boost.Asio,这三个库都是跨平台的,各有特色,对于一般的应用来说,使用这些库都是没什么问题。由于C++标准库和boost库的亲缘关系,我经常使用boost中其它的库,所以选择了Asio库。在网络上搜索了大家对Asio的评价,发现Asio库作为跨平台的网络库还是相当优秀的。
Linux系统高效网络I/O是epoll,windows系统高效的网络I/O是iocp,epoll是一种同步I/O复用技术,iocp是异步I/O。同步I/O指内核通知应用程序数据有了,应用程序可以获取了;异步I/O是内核负责读数据,读好后通知应用程序可以用了。所以一般来说异步I/O相比同步I/O的效率更高一些,但是Linux中异步I/O(aio)并不比epoll高效。为了使的Asio库跨平台,最终Asio选择Linux系统在epoll的基础上用iocp的思想的封装一层,这在一定上损失了Linux平台I/O的效率。总的来说Asio网络通信库是主动器模式(proactor),而libevent使用的是reactor模式。
二、反应器模式/主动器模式
反应器是比较容易理解的I/O模式,也是使用比较多的模式。主要内容来自于《IO设计模式:Reactor和Proactor对比》。

Reactor包含如下角色:
- Handle 句柄;用来标识socket连接或是打开文件;
- Synchronous Event Demultiplexer:同步事件多路分解器:由操作系统内核实现的一个函数;用于阻塞等待发生在句柄集合上的一个或多个事件;(如select/epoll;)
- Event Handler:事件处理接口
- Concrete Event HandlerA:实现应用程序所提供的特定事件处理逻辑;
- Reactor:反应器,定义一个接口,实现以下功能:
1)供应用程序注册和删除关注的事件句柄;
2)运行事件循环;
3)有就绪事件到来时,分发事件到之前注册的回调函数上处理;

Proactor主动器模式包含如下角色
- Handle 句柄;用来标识socket连接或是打开文件;
- Asynchronous Operation Processor:异步操作处理器;负责执行异步操作,一般由操作系统内核实现;
- Asynchronous Operation:异步操作
- Completion Event Queue:完成事件队列;异步操作完成的结果放到队列中等待后续使用
- Proactor:主动器;为应用程序进程提供事件循环;从完成事件队列中取出异步操作的结果,分发调用相应的后续处理逻辑;
- Completion Handler:完成事件接口;一般是由回调函数组成的接口;
- Concrete Completion Handler:完成事件处理逻辑;实现接口定义特定的应用处理逻辑;
主动和被动以主动写为例,Reactor将handle放到select(),等待可写就绪,然后调用write()写入数据;写完处理后续逻辑;Proactor调用aoi_write后立刻返回,由内核负责写操作,写完后调用相应的回调函数处理后续逻辑;可以看出,Reactor被动的等待指示事件的到来并做出反应;它有一个等待的过程,做什么都要先放入到监听事件集合中等待handler可用时再进行操作;Proactor直接调用异步读写操作,调用完后立刻返回。
三、基本使用
1.基本的同步客户端架构
using boost::asio;
io_service service;
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), );
ip::tcp::socket sock(service);
sock.connect(ep);
2.基本的同步服务器架构
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
io_service service;
ip::tcp::endpoint ep( ip::tcp::v4(), )); // listen on 2001
ip::tcp::acceptor acc(service, ep);
while ( true) {
socket_ptr sock(new ip::tcp::socket(service));
acc.accept(*sock);
boost::thread( boost::bind(client_session, sock));
}
void client_session(socket_ptr sock) {
while ( true) {
char data[];
size_t len = sock->read_some(buffer(data));
if ( len > )
write(*sock, buffer("ok", ));
}
3.基本的异步客户端架构
using boost::asio;
io_service service;
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), );
ip::tcp::socket sock(service);
sock.async_connect(ep, connect_handler);
service.run();
void connect_handler(const boost::system::error_code & ec) {
// 如果ec返回成功我们就可以知道连接成功了
}
4.基本的异步服务器架构
using boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
io_service service;
ip::tcp::endpoint ep( ip::tcp::v4(), )); // 监听端口2001
ip::tcp::acceptor acc(service, ep);
socket_ptr sock(new ip::tcp::socket(service));
start_accept(sock);
service.run();
void start_accept(socket_ptr sock) {
acc.async_accept(*sock, boost::bind( handle_accept, sock, _1) );
}
void handle_accept(socket_ptr sock, const boost::system::error_code &
err) {
if ( err) return;
// 从这里开始, 你可以从socket读取或者写入
socket_ptr sock(new ip::tcp::socket(service));
start_accept(sock);
}
boost::asio基本使用的更多相关文章
- c++ boost asio库初学习
前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...
- 如何在多线程leader-follower模式下正确的使用boost::asio。
#include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...
- BOOST.Asio——Tutorial
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- BOOST.Asio——Overview
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- boost asio sync
Service: #include<boost/asio.hpp> #include<boost/thread.hpp> #include<iostream> #i ...
- 网络库crash以及boost asio strand dispath分析
最近在做服务器的稳定性的相关测试,服务器的网络底层使用的是boost asio,然后自己做的二次封装以更好的满足需求. 服务器昨天晚上发现crash了一次,之前测试了将近半个多月,有一次是莫名的退出了 ...
- boost asio tcp server 拆分
从官方给出的示例中对于 boost::asio::ip::tcp::acceptor 类的使用,是直接使用构造函数进行构造对象,这一种方法用来学习是一个不错的方式. 但是要用它来做项目却是不能够满足我 ...
- boost::asio 使用实例
#include <iostream> #include <boost/asio.hpp> using namespace std; using namespace boost ...
- boost.asio源码剖析(四) ---- asio中的泛型概念(concepts)
* Protocol(通信协议) Protocol,是asio在网络编程方面最重要的一个concept.在第一章中的levelX类图中可以看到,所有提供网络相关功能的服务和I/O对象都需要Protoc ...
- boost.asio源码剖析(五) ---- 泛型与面向对象的完美结合
有人说C++是带类的C:有人说C++是面向对象编程语言:有人说C++是面向过程与面向对象结合的语言.类似的评论网上有很多,虽然正确,却片面,是断章取义之言. C++是实践的产物,C++并没有为了成为某 ...
随机推荐
- static关键字(二)作用总结
静态变量和静态方法 static关键字最基本的用法是: 1.被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来 2.被static修饰的方法属于类方法,可以通过 ...
- [翻译]CSS3 Media Queries
Media Queries Official Manual:http://www.w3.org/TR/css3-mediaqueries/ 原文链接:http://www.smashingmagazi ...
- FP-Growth in Spark MLLib
并行FP-Growth算法思路 上图的单线程形成的FP-Tree. 分布式算法事实上是对FP-Tree进行分割,分而治之 首先,假设我们只关心...|c这个conditional transactio ...
- AndroidPn消息推送
接着前面的工作,消息接收之后,要推送给不同的客户端.关于消息推送,网上有很多方式,http长连接,xmpp协议,还有一个谷歌的貌似叫C2DM的东西. 在此之前,用openfire做了一个小demo,例 ...
- BCP IN示例
参考:http://www.cnblogs.com/qanholas/archive/2011/07/05/2098616.html bcp {dbtable | query} {in | out | ...
- jvm linux 时区设置
# 背景 在接入集团一个平台的时候,发现录制某个接口到测试环境回放,发现接口入参一致,一个start_day 一个end_day,但回放的时候会多调用一次数据库查询,很是奇怪: 查阅业务代码,发现确实 ...
- ADO.NET系列之DataAdapter对象
ADO.NET系列之Connection对象 ADO.NET系列之Command对象 ADO.NET系列之DataAdapter对象 ADO.NET系列之事务和调用存储过程 我们前两篇文章介绍了ADO ...
- Visual Studio Code 学习.net core初体验
一,安装 最近在用 Visual Studio Code 学习.net core ,记录下学习的过程,首先去官网下载最新的.net core2.1安装包,有windows 和mac,根据自己的开发环境 ...
- 使用Spring Boot,Spring Cloud和Docker实现微服务架构
https://github.com/sqshq/PiggyMetrics Microservice Architecture with Spring Boot, Spring Cloud a ...
- 20164317 《网络对抗技术》Exp5 MSF基础应用
基础问题回答 (1)用自己的话解释什么是exploit,payload,encode. exploit: 是指攻击者或渗透测试者利用一个系统.应用或服务中的安全漏洞所进行的攻击行为, 包括利用缓冲区溢 ...