You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Boost ASIO阻塞与异步TCP回显服务器功能差异咨询

Blocking vs Async TCP Echo Server:Boost ASIO示例的核心差异

我正在学习Boost ASIO,参考官方示例中的代码。观察blocking_tcp_echo_server可知,该示例通过线程处理多客户端连接,现咨询:该实现与async_tcp_echo_server示例之间存在哪些功能差异?

Blocking TCP Echo Server 代码

#include <cstdlib>
#include <iostream>
#include <thread>
#include <utility>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

const int max_length = 1024;

void session(tcp::socket sock)
{
  try
  {
    for (;;)
    {
      char data[max_length];

      boost::system::error_code error;
      size_t length = sock.read_some(boost::asio::buffer(data), error);
      if (error == boost::asio::error::eof)
        break; // Connection closed cleanly by peer.
      else if (error)
        throw boost::system::system_error(error); // Some other error.

      boost::asio::write(sock, boost::asio::buffer(data, length));
    }
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception in thread: " << e.what() << "\n";
  }
}

void server(boost::asio::io_context& io_context, unsigned short port)
{
  tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
  for (;;)
  {
    std::thread(session, a.accept()).detach();
  }
}

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
      return 1;
    }

    boost::asio::io_context io_context;

    server(io_context, std::atoi(argv[1]));
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

Async TCP Echo Server 代码

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio/ts/buffer.hpp>
#include <boost/asio/ts/internet.hpp>

using boost::asio::ip::tcp;

class session
  : public std::enable_shared_from_this<session>
{
public:
  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(boost::asio::buffer(data_, max_length),
        [this, self](boost::system::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            do_write(length);
          }
        });
  }

  void do_write(std::size_t length)
  {
    auto self(shared_from_this());
    boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
        [this, self](boost::system::error_code ec, std::size_t /*length*/)
        {
          if (!ec)
          {
            do_read();
          }
        });
  }

  tcp::socket socket_;
  enum { max_length = 1024 };
  char data_[max_length];
};

class server
{
public:
  server(boost::asio::io_context& io_context, short port)
    : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)),
      socket_(io_context)
  {
    do_accept();
  }

private:
  void do_accept()
  {
    acceptor_.async_accept(socket_,
        [this](boost::system::error_code ec)
        {
          if (!ec)
          {
            std::make_shared<session>(std::move(socket_))->start();
          }

          do_accept();
        });
  }

  tcp::acceptor acceptor_;
  tcp::socket socket_;
};

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: async_tcp_echo_server <port>\n";
      return 1;
    }

    boost::asio::io_context io_context;

    server s(io_context, std::atoi(argv[1]));

    io_context.run();
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

核心功能差异

  • 线程模型与资源开销

    • Blocking版本:每接入一个客户端就创建独立线程(std::thread(session, a.accept()).detach()),线程数量随客户端数线性增长。大量连接会引发频繁的线程上下文切换,且每个线程的栈内存会消耗大量系统资源,扩展性受限。
    • Async版本:基于单线程事件循环(io_context.run())处理所有I/O事件,无需为每个连接分配线程。即使面对上万级并发连接,也仅需少量线程(甚至单线程)即可支撑,资源开销极低。
  • I/O操作模式

    • Blocking版本:使用阻塞式API(read_some、write、accept),线程在等待I/O完成时会被挂起,直到操作结束才继续执行。比如主线程会卡在a.accept()直到有新连接,工作线程会卡在read_some()直到收到数据。
    • Async版本:使用异步API(async_accept、async_read_some、async_write),调用后立即返回,I/O完成时通过回调函数触发后续逻辑。事件循环负责监听I/O就绪事件,全程无阻塞等待。
  • 编程范式

    • Blocking版本:同步线性编程逻辑,代码顺序执行,符合常规思维,调试和编写门槛低。比如session函数里的循环直接实现"读-写-循环"的逻辑,清晰直观。
    • Async版本:采用异步回调范式(Reactor模式),业务逻辑被拆分为多个回调函数(do_read、do_write、do_accept),通过链式调用流转。需要处理对象生命周期(比如用enable_shared_from_this保证回调期间session对象不被销毁),学习曲线更陡。
  • 并发处理能力

    • Blocking版本:并发能力受限于系统最大线程数,当连接数超过数百个时,线程切换开销会严重拖累性能,甚至导致系统资源耗尽。
    • Async版本:事件驱动模型天然支持高并发,能高效处理数万甚至数十万个并发连接,是高性能网络服务的标准实现方案。
  • 错误处理方式

    • Blocking版本:依赖try-catch捕获异常,阻塞操作失败时会抛出system_error,也可通过error_code返回错误码。
    • Async版本:错误通过回调函数的error_code参数传递,示例中未使用异常捕获,直接通过ec判断操作是否成功,更贴合异步编程的错误处理习惯。

内容的提问来源于stack exchange,提问作者Neo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:39:56