boost asio 是一个轻量级的异步网络库,它有简洁,小巧,高效,有良好的可扩展性,支持高并发的IO处理,入门简单等诸多优点。boost asio在设计上采用和和ace相似的反应器(proactor)设计模式,同时内置了对多线程的支持,针对不同的平台,采用了最优的socket模型,可以说能发挥机器的最大并发处理能力。同时在设计上,asio在接口上也有良好的可扩展性,几乎每种设计元素都可以根据要求订制和扩充,可以进一步对模型进行抽象和建模来建立自己需要的开发平台。当然,asio的最大缺点就是代码调试太难了。
我们看一个asio的hello world:
#include
#include
#include
void print(const boost::asio::error& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
// 定义一个io_service,它的作用是注册服务,调用一个异步请求完成后对应的操作(一个handle)
boost::asio::io_service io;
//添加一个定时器服务,
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
//启动一个异步操作,该操作会记录于io_service 的一个队列中
t.async_wait(print);
//每个注册的服务启动工作
io.run();
//5s后,定时器时间到,print被调用,然后该handle(print)从队列中删除
return 0;
}
可以看出,对一个使用者来说,asio的原理很简单
1。定义一个IO_Service
2.向IO_Service注册一个服务,该服务可以是io服务,也可以是定时器服务,当然,你也可以自己订制一个邮件服务
3.在该服务上启动一个异步操作,这需要一个回调函数
4.如果异步操作完成,你的回调函数会被调用
5.可能的错误处理
理解asio的原理后,写一个网络通信的程序简直是依葫芦画瓢的事了
我们看一个时间查询的服务端:
#include
#include
#include
#include
#include
#include
#include
using boost::asio::ip::udp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
class udp_server
{
public:
//对象建立时,注册了udp的socket服务,接着就开始了一个异步的接收操作
udp_server(boost::asio::io_service& io_service)
: socket_(io_service, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
//启动的异步操作
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), //接收缓冲区
remote_endpoint_, //存储请求的客户地址,ip+port
boost::bind(&udp_server::handle_receive, this, //构造一个回调函数,实际调用了成员函数handle_receive,具体见boost::bind
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
}
void handle_receive(const boost::asio::error& error,
std::size_t /*bytes_transferred*/)
{
//接到客户端的信息,忽略了请求内容,直接发回本机的时间,发送也是一个异步操作
if (!error || error == boost::asio::error::message_size)
{
boost::shared_ptr message(
new std::string(make_daytime_string()));
socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&udp_server::handle_send, this, message,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
start_receive();
}
}
//发送完成,忽略
void handle_send(boost::shared_ptr /*message*/,
const boost::asio::error& /*error*/, std::size_t /*bytes_transferred*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array recv_buffer_;
};
int main()
{
try
{
boost::asio::io_service io_service;
udp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
可以看到,用asio开发一个网络服务端的程序一件多么简单的事。对此程序稍加改动,我们就可以建立一个支持多线程,高并发的网络服务程序。
后面我们将继续分析asio的多线程支持,多缓冲,网络流等更好的基础特性。