asio环境搭建

DinS          Written on 2017/10/27

本专题将开始介绍ASIO,一个非常好用的c++网络编程库。阅读本专题前建议阅读《socket概述》等文章,掌握基本的网络编程概念。

一、Asio是什么?

使用SocketAPI过于原始,而且会遇到可移植性问题,于是网上有许多第三方的网络通信库,对socket使用进行了封装和抽象。那么问题是为什么使用Asio?
从名字上看,Asio跟socket没什么关系。如果进入Asio的官网,其口号是think asynchronously,很明显,这是一个异步I/O库,网络通信呢?
实际上读写硬盘和网络通信都是典型的I/O操作,这个Asio最初是针对socket做的,但是后来发展到异步I/O都可以处理,这就是名字的由来。不过使用Asio主要还是使用其网络通信内容,简单的异步操作在c++11的future中已经可以做到了,见《c++异步调用机制》。

接下来回答为什么选择Asio而不是其他的库,比如ACE或者libevent等。
1.Asio属于轻量级的网络通信库,对socket提供了抽象但是又不过于复杂,学习成本低。
2.其语言风格属于现代c++风格,跟std中的用法相近,容易掌握和理解。
3.Asio有独立版和Boost版,内容是相似的。既然能够加入Boost,至少说明质量可以保证,至少不会比其他的差。而且有可能将来从Boost加入的C++语言层面。

“Talk is cheap, show me the code”。我想将ASIO的代码跟Python代码对比一下。

众所周知,python以其简洁著称,一段socket客户端只要区区几行,确实是厉害。以上代码是我学习python for everybody时写的,用socket做http通讯。

结果:

python的代码可以作为一个评价标准。再来看看ASIO的代码。

非常的简洁精炼,跟python相比并不差,甚至我认为还要更加简洁。结果:

读者将两份代码对比一下,就应该能够理解使用ASIO的优势了,至少跟其他c++网络通讯库相比。

当然在进入具体的ASIO使用方法前,先需要搭建环境。

二、配置环境

既然Asio是第三方库,那么自然要配置环境。
首先去官网下载Asio库(非Boost版),然后新建一个工程。
这里使用的是asio-1.10.6和VS2015。解压,发现Asio里面有一堆文件,doc是说明文件,src里有示例,真正用到程序里的是include文件夹。

把include文件夹拷贝到工程目录下,换个名字,比如Asio。

然后进到开发环境,加入头文件#include “asio.hpp”,这个asio.hpp就在拷贝过来的文件夹里。然而这时会报错,找不到该头文件,此时需要设置项目属性。

C/C++常规->附加包含目录->填入文件夹绝对路径。这样就可以找到头文件了。

现在包含头文件不会报错了,编译一下试试。

报错,主要是找不到Boost库中的内容。这不奇怪,因为Asio本来就有Boost版本,也用到了Boost中的内容,但是咱们下载的是非Boost版,在C++11标准下可以独立编译,方法是加入指定字段。
在VS中进入项目属性->预处理器。

在预处理器中定义ASIO_STANDALONE,这就告诉编译器不要去找Boost库。

然后编译。

成功了,但是还需要进一步处理。
这里让我们定义windows平台的version,为什么需要这一步稍后说明,这里先如此处理。

在预处理器中定义windows版本号,具体的内容可见https://zhidao.baidu.com/question/557130216.html
这里定义成win7版本,然后再编译。

成功了,注意这里仅仅是把Debug配置了,如果做Release版还要如法炮制。

我们定义一个asio里面的对象,再编译也可以,这下环境搭建没问题了。

顺带提一句,这种使用方法实际上是把ASIO的源代码加入了工程中,而一般来说第三方库都是用lib的形式引入的,这样做是否恰当呢?ASIO属于不太一样的第三方库,注意其头文件是hpp,遵循boost的传统,这意味着可以不需要编译就直接使用。因此这样使用没什么问题。

三、核心概念

现在回答为什么需要指定操作系统版本以及这个asio::io_service类是什么。
我们知道socket的实现依赖于操作系统,所以Asio要利用操作系统的信息优化程序,另外I/O操作必定跟操作系统打交道,所以为了可移植性程序员需要与操作系统隔离开。
这个io_service就是Asio库提供的与操作系统打交道的对象。下图来自Asio的说明文档,比较直观表达了同步和异步的核心思路,注意io_service的地位。

这个是非异步模式的示意图,io_service将程序与操作系统隔离,并且提供了I/O对象供程序使用。

这个是异步模式的示意图,也是ASIO主力军。程序通过注册回调句柄让io_service自主完成任务。

前期工作完成后,就开始进入正题,见《asio基础使用方法》。