Standalone Asio是轻量跨平台C++网络库,支持同步/异步I/O;需配置-std=c++17和-DASIO_STANDALONE;核心为io_context事件循环、shared_from_this生命周期管理及error_code错误处理。

Asio 是一个跨平台的 C++ 网络编程库,其非 Boost 版本(即 standalone Asio)以头文件为主、无依赖、轻量易集成,非常适合学习和中小型项目。它支持同步与异步 I/O,而异步模型正是高性能网络服务的核心。下面以最简实践路径带你入门。
一、获取与配置 standalone Asio
官网地址:https://www.php.cn/link/83b7b19e6be902a7bab8244f0d83481f。下载最新 release(如 asio-X.Y.Z.tar.gz),解压后只需将 include/asio 和 include/boost(仅含 asio 所需的少量 boost 头文件,实际可忽略)加入编译器 include 路径即可。C++17 或更高版本推荐启用:
-
-std=c++17(支持std::optional、std::variant等现代特性) -
-DASIO_STANDALONE(显式启用 standalone 模式,禁用 Boost 依赖) - Windows 下还需定义
WIN32_LEAN_AND_MEAN避免 Windows 头冲突
二、异步 TCP 服务器:从 accept 到 read
核心思想是“发起操作 → 注册回调 → 继续运行”,不阻塞线程。以下是一个监听端口、接受连接并读取一行数据的最小异步服务器示例:
#include#include #include #include using asio::ip::tcp; struct session : std::enable_shared_from_this { tcp::socket socket_; std::array buffer_; explicit session(tcp::socket socket) : socket_(std::move(socket)) {} void start() { do_read(); } private: void do_read() { auto self = shared_from_this(); socket_.async_read_some( asio::buffer(buffer_), [self](const std::error_code& ec, std::size_t length) { if (!ec) { std::cout << "Received: " << std::string(self->buffer_.data(), length); self->do_read(); // 继续读 } }); } }; struct server { asio::io_context& ioc_; tcp::acceptor acceptor_; server(asio::io_context& ioc, short port) : ioc_(ioc), acceptor_(ioc, tcp::endpoint(tcp::v4(), port)) { do_accept(); } private: void do_accept() { acceptor_.async_accept([this](const std::error_code& ec, tcp::socket socket) { if (!ec) { std::make_shared (std::move(socket))->start(); } do_accept(); // 接受下一个连接 }); } }; int main() { asio::io_context ioc; server s(ioc, 8080); ioc.run(); // 启动事件循环 }
注意点:
-
shared_from_this()保证 session 对象在回调执行期间不被销毁 - 所有异步操作(
async_accept、async_read_some)立即返回,不等待完成 -
io_context::run()是单线程事件循环入口;多线程可用run_work_guard+ 多个线程调用run()
三、异步 DNS 解析与客户端连接
客户端常需解析域名再连接。Asio 提供 ip::tcp::resolver 异步解析:
PHP是一种功能强大的网络程序设计语言,而且易学易用,移植性和可扩展性也都非常优秀,本书将为读者详细介绍PHP编程。 全书分为预备篇、开始篇和加速篇三大部分,共9章。预备篇主要介绍一些学习PHP语言的预备知识以及PHP运行平台的架设;开始篇则较为详细地向读者介绍PKP语言的基本语法和常用函数,以及用PHP如何对MySQL数据库进行操作;加速篇则通过对典型实例的介绍来使读者全面掌握PHP。 本书
void connect_to_host(asio::io_context& ioc, const std::string& host, const std::string& port) {
tcp::resolver resolver(ioc);
resolver.async_resolve(
host, port,
[&ioc](const std::error_code& ec, tcp::resolver::results_type results) {
if (!ec) {
tcp::socket socket(ioc);
asio::async_connect(socket, results,
[&socket](const std::error_code& ec, const tcp::endpoint&) {
if (!ec) {
std::cout << "Connected!\n";
// 后续 send / async_read...
}
});
}
});
}
关键细节:
- 解析结果是 endpoint 列表(支持 IPv4/IPv6 双栈),
async_connect会自动尝试直到成功或全部失败 - 不要在 lambda 中直接捕获
socket值语义对象——应使用智能指针或确保生命周期,否则可能析构后访问
四、错误处理与资源管理要点
异步操作的错误统一通过 std::error_code 回调参数传递,常见错误码如:
-
asio::error::operation_aborted:对象销毁时未完成的操作被取消(正常,无需报错) -
asio::error::eof:对端关闭连接(read 返回 0 字节) -
asio::error::connection_reset:连接被重置(如对端崩溃)
资源安全建议:
- 用
std::shared_ptr管理会跨回调生命周期的对象(如 session、socket) - 主动关闭连接时调用
socket.close(ec),避免残留 pending 操作 - 若需取消所有异步操作,调用
socket.cancel()或io_context.stop()(后者会终止 run)
不复杂但容易忽略:异步不是“多线程”,而是“非阻塞+回调驱动”。理解 io_context 的角色、对象生命周期和错误传播机制,比写更多 handler 更重要。写几个 echo server/client 跑通,再逐步加超时、SSL、协程(Asio 支持 C++20 coroutine)就顺了。










