利用boost::asio实现一个简单的服务器框架

  boost::asio是一个高性能的网络开发库,Windows下使用IOCP,Linux下使用epoll。与ACE不同的是,它并没有提供一个网络框架,而是采取组件的方式来提供应用接口。但是对于常见的情况,采用一个好用的框架还是能够简化开发过程,特别是asio的各个异步接口的用法都相当类似。
  受到 SP Server 框架的影响,我使用asio大致实现了一个多线程的半异步半同步服务器框架,以下是利用它来实现一个Echo服务器:

1. 实现回调:
  1. static void onSessionStarted(RequestPtr const& request, ResponsePtr const& response) {
  2.    request->setReadMode(Session::READ_LN); // 设置为行读取
  3. }
  4. static void onSession(RequestPtr const& request, ResponsePtr const& response) {
  5.    print(request->message()); //打印收到的消息
  6.    response->addReply(request->message()); //回送消息
  7.    response->close();
  8. }
复制代码
说明:close()是一个关闭请求,它并不马上关闭Session,而是等待所有与该Session相关的异步操作全部结束后才关闭。

2. 一个单线程的Echo服务器:
  1. void server_main() {
  2. unsigned short port = 7;
  3. AsioService svc;
  4. AsioTcpServer tcp(svc, port);
  5. svc.callbacks().sessionStarted = &onSessionStarted;
  6. svc.callbacks().sessionHandle = &onSession;
  7. svc.run();
  8. }
复制代码
3. 一个多线程的Echo服务器(半异步半同步:一个主线程,4个工作者线程)
  1. void server_main2() {
  2. unsigned short port = 7;
  3. int num_threads = 4;
  4. AsioService svc;
  5. AsioService worker(AsioService::HAS_WORK);
  6. AsioTcpServer tcp(svc, port);
  7. svc.callbacks().sessionStarted = worker.wrap(&onSessionStarted);
  8. svc.callbacks().sessionHandle = worker.wrap(&onSession);
  9. AsioThreadPool thr(worker, num_threads);
  10. svc.run();
  11. }
复制代码
  有了这样一个思路,实现起来就很容易了。重点是以下两点:
  1。缓冲区的管理与内存池的使用
  2。为了保证Session的线程安全,必须要设置一个挂起状态。
     
     还有一个好处,就是完全隔绝了asio的应用接口,不用再忍受asio漫长的编译时间了。代码就不贴在这里了,有兴趣的可以通过email 探讨。(说明,这里只提出一个思路,不再提供源代码,请各位见谅)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的使用 boost::asio 库编写的服务器示例: ```c++ #include <iostream> #include <boost/asio.hpp> using namespace boost::asio; using namespace boost::asio::ip; 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(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()); async_write(socket_, 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(io_service& ios, short port) : acceptor_(ios, tcp::endpoint(tcp::v4(), port)), socket_(ios) { 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: server <port>" << std::endl; return 1; } io_service ios; Server s(ios, std::atoi(argv[1])); ios.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` 这个服务器使用了 boost::asio 库提供的异步 I/O 操作实现,它只会在有客户端连接时才会创建一个新的 Session 对象处理该客户端的请求,这样可以避免阻塞主线程。在 Session 对象中,我们使用了 async_read_some 和 async_write 这两个异步操作来处理客户端的读写请求,这样可以保证多个客户端之间互不干扰。最后,在 main 函数中,我们启动了一个 Server 对象,并调用了 io_service 的 run 方法来启动事件循环。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值