Boost asio 应用
1.1 Boost asio 介绍
Boost.Asio是一个跨平台的、主要用于网络和其他一些底层输入/输出编程的C++库。Boost.Asio在网络通信、COM串行端口和文件上成功地抽象了输入输出的概念。你可以基于这些进行同步或者异步的输入输出编程。作为一个跨平台的库,Boost.Asio可以在大多数操作系统上使用。能同时支持数千个并发的连接。其网络部分的灵感来源于伯克利软件分发(BSD)socket,它提供了一套可以支持传输控制协议(TCP)socket、用户数据报协议(UDP)socket和Internet控制消息协议(IMCP)socket的API,而且如果有需要,你可以对其进行扩展以支持你自己的协议。
1.2 Boost asio 服务端封装和应用
Io_service: io_service是这个库里面最重要的类;它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用其完成处理程序。
Endpoint: 端点是使用某个端口连接到的一个地址
Acceptor:接受器
acceptor->async_accep:异步接受数据
async_read_until:异步读取数据,这个方法读取到指定的标识符就返回。注意区别async_read_some,async_read;async_read_some 只要读取到数据或者错误就返回,async_read 读取到指定长度就返回。
async_write:异步写,当然也有同步的,这里只介绍异步的。
流程图:
如下是一个使用boost asio 创建服务的关键代码部分:
1、绑定ip和端口
asio::ip::tcp::endpoint endpoint;
endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), config.port);
if(!io_service)
{
io_service = std::make_sharedasio::io_service();
}
if(!acceptor)
acceptor = std::unique_ptrasio::ip::tcp::acceptor(new asio::ip::tcp::acceptor(*io_service));
acceptor->open(endpoint.protocol());
acceptor->set_option(asio::socket_base::reuse_address(config.reuse_address));
acceptor->bind(endpoint);
2、监听端口号并run
acceptor->listen();
this->io_service->run();
3、异步接收数据
auto connection = create_connection(*io_service);
std::cout << "accept"<< std::endl;
acceptor->async_accept(*connection->socket, this, connection {
});
4、响应客户端
asio::async_write(session->connection->socket, streambuf, [self, callback](const error_code &ec, std::size_t /bytes_transferred*/) {
});
1.3 Boost asio 客户端封装和应用
客户端流程:
第一步:使用resolver 类来做域名的解析得到一个endpoint 对象,该对象中包含我们需要的ip和端口号。
第二部:使用connect方法来建立一个socket连接。
第三步:发送http请求到服务端,这里包含请求头可请求体。
第四步:通过async_read_until 来读取数据,当服务端有数据返回的时候,使用这个函数就能获取到数据。
如下是一个使用boost asio 创建Client的关键代码部分:
1、 域名解析
tcp::resolver resolver(io_service);
std::cout << host << std::endl;
tcp::resolver::query query(host, port);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
2、 建立连接
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
3、 发送数据
boost::asio::async_write(socket, request, & {
});
4、 接收数据
boost::asio::async_read_until(socket, response, "\r\n", & {
});
注意:如果想复用io_service 必须要做如下处理不然会得不到返回数据
if (io_service.stopped())
io_service.reset();