Boost.Asio是Boost库中非常著名的I/O组件,是用于网络和低层IO编程的跨平台C++库,为开发者提供了C++环境下稳定的异步模型。本文将介绍Boost库中Asio的结构及相关异步编程。
Asio三大组件
io_object
I/O对象的集合,其中包含大家所熟悉的socket、deadline_timer等对象,主要功能是提供接口给用户使用。
services服务
逻辑功能的实现者,其中包含提供定时功能的deadline_timer_service、提供socket相关功能的win_iocp_socket_service(windows平台)/reactive_socket_service(其他平台)、作为io_service功能的真正实现者win_iocp_io_service(windows平台)/task_io_service(其他平台)等等服务。
Asio核心组件
在这一层中可以理解为就是io_service,它通过关联的类service_registry将实现具体功能所需的服务组合起来,再由io_object提供接口给用户使用。
编程实例
TCP异步连接
#include <iostream>
#include <boost/asio.hpp>
// 异步连接回调函数
void on_connect(boost::system::error_code ec)
{
if (ec) // 连接失败, 输出错误码
std::cout << "async connect error:" << ec.message() << std::endl;
else // 连接成功
std::cout << "async connect ok!" << std::endl;
}
int main() {
boost::asio::io_service ios; // 创建io_service对象
boost::asio::ip::tcp::endpoint addr(
boost::asio::ip::address::from_string("127.0.0.1"), 12345); // server端地址
boost::asio::ip::tcp::socket conn_socket(ios); // 创建tcp协议的socket对象
conn_socket.async_connect(addr, &on_connect); // 发起异步连接请求
ios.run(); // 调用io_service::run, 等待异步操作结果
std::cin.get();
return 0;
}
TCP异步接受连接
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
// 异步连接回调函数
void on_accept(boost::system::error_code ec, boost::asio::ip::tcp::socket * socket_ptr)
{
if (ec) // 连接失败, 输出错误码
std::cout << "async accept error:" << ec.message() << std::endl;
else // 连接成功
std::cout << "async accept from (" << socket_ptr->remote_endpoint() << ")" << std::endl;
// 断开连接, 释放资源.
socket_ptr->close(), delete socket_ptr;
}
int main() {
boost::asio::io_service ios; // 创建io_service对象
boost::asio::ip::tcp::endpoint addr(
boost::asio::ip::address::from_string("0.0.0.0"), 12345); // server端地址
boost::asio::ip::tcp::acceptor acceptor(ios, addr, false); // 创建acceptor对象
boost::asio::ip::tcp::socket * socket_ptr = new boost::asio::ip::tcp::socket(ios);
acceptor.async_accept(*socket_ptr
, boost::bind(&on_accept, boost::asio::placeholders::error, socket_ptr)); // 调用异步accept请求
ios.run(); // 调用io_service::run, 等待异步操作结果
std::cin.get();
return 0;
}
TCP异步读写数据
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/array.hpp>
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr_t;
typedef boost::array<char, 128> buffer_t;
typedef boost::shared_ptr<buffer_t> buffer_ptr_t;
// 异步读数据回调函数
void on_read(boost::system::error_code ec
, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)
{
if (ec)
std::cout << "async write error:" << ec.message() << std::endl;
else
{
std::cout << "async read size:" << len;
std::cout << " info:" << std::string((char*)buffer_ptr->begin(), len) << std::endl;
// auto release socket and buffer.
}
}
// 异步写数据回调函数
void on_write(boost::system::error_code ec
, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)
{
if (ec)
std::cout << "async write error:" << ec.message() << std::endl;
else
{
std::cout << "async write size:" << len << std::endl;
socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())
, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
}
// 异步连接回调函数
void on_accept(boost::system::error_code ec, socket_ptr_t socket_ptr)
{
if (ec) // 连接失败, 输出错误码
{
std::cout << "async accept error:" << ec.message() << std::endl;
}
else // 连接成功
{
std::cout << "async accept from (" << socket_ptr->remote_endpoint() << ")" << std::endl;
buffer_ptr_t buffer_ptr(new buffer_t);
strcpy_s((char*)buffer_ptr->begin(), buffer_t::size(), "abcdefg");
socket_ptr->async_write_some(boost::asio::buffer(buffer_ptr.get(), strlen((char*)buffer_ptr->begin()))
, boost::bind(&on_write, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
}
int main() {
boost::asio::io_service ios; // 创建io_service对象
boost::asio::ip::tcp::endpoint addr(
boost::asio::ip::address::from_string("0.0.0.0"), 12345); // server端地址
boost::asio::ip::tcp::acceptor acceptor(ios, addr, false); // 创建acceptor对象
socket_ptr_t socket_ptr(new boost::asio::ip::tcp::socket(ios));
acceptor.async_accept(*socket_ptr
, boost::bind(&on_accept, boost::asio::placeholders::error, socket_ptr)); // 调用异步accept请求
ios.run(); // 调用io_service::run, 等待异步操作结果
std::cout << "press enter key...";
std::cin.get();
return 0;
}
TCP强制关闭连接
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/array.hpp>
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr_t;
typedef boost::array<char, 128> buffer_t;
typedef boost::shared_ptr<buffer_t> buffer_ptr_t;
// 异步读数据回调函数
void on_read(boost::system::error_code ec
, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)
{
if (ec) // 连接失败, 输出错误码
{
std::cout << "async read error:" << ec.message() << std::endl;
}
}
// 异步写数据回调函数
void on_write(boost::system::error_code ec
, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)
{
if (ec) // 连接失败, 输出错误码
{
std::cout << "async write error:" << ec.message() << std::endl;
}
}
// 异步连接回调函数
void on_accept(boost::system::error_code ec, socket_ptr_t socket_ptr)
{
if (ec) // 连接失败, 输出错误码
{
std::cout << "async accept error:" << ec.message() << std::endl;
}
else // 连接成功
{
std::cout << "async accept from (" << socket_ptr->remote_endpoint() << ")" << std::endl;
{
buffer_ptr_t buffer_ptr(new buffer_t);
strcpy_s((char*)buffer_ptr->begin(), buffer_t::size(), "abcdefg");
socket_ptr->async_write_some(boost::asio::buffer(buffer_ptr.get(), strlen((char*)buffer_ptr->begin()))
, boost::bind(&on_write, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
{
buffer_ptr_t buffer_ptr(new buffer_t);
socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())
, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
/// 强制关闭连接
socket_ptr->close(ec);
if (ec)
std::cout << "close error:" << ec.message() << std::endl;
}
}
int main()
{
boost::asio::io_service ios; // 创建io_service对象
boost::asio::ip::tcp::endpoint addr(
boost::asio::ip::address::from_string("0.0.0.0"), 12345); // server端地址
boost::asio::ip::tcp::acceptor acceptor(ios, addr, false); // 创建acceptor对象
socket_ptr_t socket_ptr(new boost::asio::ip::tcp::socket(ios));
acceptor.async_accept(*socket_ptr
, boost::bind(&on_accept, boost::asio::placeholders::error, socket_ptr)); // 调用异步accept请求
socket_ptr.reset();
ios.run(); // 调用io_service::run, 等待异步操作结果
std::cout << "press enter key...";
std::cin.get();
return 0;
}
TCP优雅地关闭连接
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/array.hpp>
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr_t;
typedef boost::array<char, 32> buffer_t;
typedef boost::shared_ptr<buffer_t> buffer_ptr_t;
// 异步读数据回调函数
void on_read(boost::system::error_code ec
, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)
{
static int si = 0;
if (ec) // 连接失败, 输出错误码
{
std::cout << "async read(" << si++ << ") error:" << ec.message() << std::endl;
socket_ptr->shutdown(boost::asio::socket_base::shutdown_receive, ec);
socket_ptr->close(ec);
if (ec)
std::cout << "close error:" << ec.message() << std::endl;
}
else
{
std::cout << "read(" << si++ << ") len:" << len << std::endl;
socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())
, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
}
// 异步写数据回调函数
void on_write(boost::system::error_code ec
, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)
{
if (ec) // 连接失败, 输出错误码
{
std::cout << "async write error:" << ec.message() << std::endl;
}
else
{
/// 优雅地关闭连接
socket_ptr->shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
if (ec)
std::cout << "shutdown send error:" << ec.message() << std::endl;
}
}
// 异步连接回调函数
void on_accept(boost::system::error_code ec, socket_ptr_t socket_ptr)
{
if (ec) // 连接失败, 输出错误码
{
std::cout << "async accept error:" << ec.message() << std::endl;
}
else // 连接成功
{
std::cout << "async accept from (" << socket_ptr->remote_endpoint() << ")" << std::endl;
{
buffer_ptr_t buffer_ptr(new buffer_t);
socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())
, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
{
buffer_ptr_t buffer_ptr(new buffer_t);
strcpy_s((char*)buffer_ptr->begin(), buffer_t::size(), "abcdefg");
socket_ptr->async_write_some(boost::asio::buffer(buffer_ptr.get(), strlen((char*)buffer_ptr->begin()))
, boost::bind(&on_write, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred
, socket_ptr, buffer_ptr));
}
}
}
int main()
{
boost::asio::io_service ios; // 创建io_service对象
boost::asio::ip::tcp::endpoint addr(
boost::asio::ip::address::from_string("0.0.0.0"), 12345); // server端地址
boost::asio::ip::tcp::acceptor acceptor(ios, addr, false); // 创建acceptor对象
socket_ptr_t socket_ptr(new boost::asio::ip::tcp::socket(ios));
acceptor.async_accept(*socket_ptr
, boost::bind(&on_accept, boost::asio::placeholders::error, socket_ptr)); // 调用异步accept请求
socket_ptr.reset();
ios.run(); // 调用io_service::run, 等待异步操作结果
std::cout << "press enter key...";
std::cin.get();
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。